home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / allswag.zip / KEYBOARD.SWG < prev    next >
Text File  |  1993-12-08  |  173KB  |  1 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00057         KEYBOARD I/O ROUTINES                                             1      05-28-9313:49ALL                      SWAG SUPPORT TEAM        Stuff Keyboard Buffer    IMPORT              19          {πROB PERELMANππ> I want to put the character and scan code for ALT-V in the keyboard buffer.π> In fact I would like to put it in there twice. I need it to be in theπ> buffer so that when my program terminates the parent process will act onπ> that key.ππ{π If this is being used with Turbo Pascal Version 3.0, you MUST setπ the C and U compiler directives to MINUS!π If this is being used with Turbo Pascal Version 4.0, then set theπ CheckBreak variable  of the CRT unit to FALSE!π}ππUsesπ  Crt;ππTypeπ  BufType = Array[30..62] of Byte;ππVarπ  Head    : Integer Absolute $0000 : $041A;    { Location of head of buffer  }π  Tail    : Integer Absolute $0000 : $041C;    { Location of tail of buffer  }π  KBDBuf  : BufType absolute $0000 : $041E;    { Absolute location of buffer }π  S       : String[80];                        { Input string                }ππProcedure StufftheBuff (Ch : Char; Code : Byte);πVarπ  TempTail : Integer;                          { Temporary holding of Tail  }πBeginπ  TempTail := Tail;                           { Store the Temporary Tail   }π  Tail := Tail + 2;                           { Incriment Tail to next pos }π  If Head = Tail Then                         { Is the buffer full?        }π  Beginπ    Tail := TempTail;                        { Reset to previos value     }π    Sound(440);                              { Beep the user              }π    Delay(400);                              { Delay for the beep         }π    NoSound;                                 { Turn off the sound         }π  Endπ  Elseπ  Beginπ    KBDBuf[TempTail] := Ord(Ch);              { Put the ASCII value in buf }π    KBDBuf[TempTail + 1] := Code;             { Put extended keypress valu }π    If Tail > 60 then                         { Last position. Wrap?       }π      Tail := 30;                             { Wrap to 1st position       }π  End;πEnd;ππBeginπ  ClrScr;                                     { Clear the Screen           }π  StufftheBuff ( 'D',0 );                     { Start stuffing the buffer  }π  StufftheBuff ( 'I',0 );                     { Another stuff of the Buffer}π  StufftheBuff ( 'R',0 );                     {    "      "    "  "    "   }π  StufftheBuff ( #13,0 ); { CR }              { Stuff a carriage return    }πEnd.π                           2      05-28-9313:49ALL                      SWAG SUPPORT TEAM        Clear Keyboard Buffer    IMPORT              8           {πEDWIN CALIMBOππ║ I need to know how I can clear the keyboard buffer.π║ The reason I need to do this is that in a loop I'm reading inπ║ one Character and then calling a Procedure which returns to theπ║ loop For the next Character to be read.  But sometimes it takes theπ║ next Character in the buffer that my have been a result of just holdingπ║ down a key For to long.πππ  You can clear any keys in the keyboard buffer by using the following loop:π}π      While KeyPressed Doπ        ch := ReadKey;π{π  Another way to clear the keyboard buffer is to set the keyboard headπ  equal to the keyboard tail and the keyboard buffer as a circular buffer.π  You can set the tail equal to the head this way:π}π      MemW[$0000:$041C] := MemW[$0000:$041A];      { flush keyboard buffer }π                                                                                                                     3      05-28-9313:49ALL                      SWAG SUPPORT TEAM        INT09 Keyboard handler #1IMPORT              21          {π>  Does anybody know of a way to reWrite the keyboard routines, to be ablπ>  to read several keys at once? ReadKey will only read the last keypressπ>  anything else I've tried can only read the last key you have pressed dπ>π>  For example, in many games it will let you move Forward (With the Forwπ>  arrow key) and shoot at the same time, With the space bar...Any suggesπ}ππUnit POLL ;         { polled keyboard handler }π                    { does not support F11 or F12 keys } InterfaceππConstπ   EscKey = 1 ;    { key codes }π   aKey = 30 ;     { see TP 6 Programmers guide p 354 }π   sKey = 31 ;π   endKey = 79 ;π   DownKey = 80 ;ππVarπ   KeyTable : Array[ 1..127 ] of Boolean ; { KeyTable[ x ] is True when key xπis pressed } { and stays True Until key x is released }ππImplementationππUses Dos, KeyIntr ;  { keyboard interrupt support }ππVarπ   OldInt09 : Pointer ;π   ExitSave : Pointer ;ππ{$F+} Procedure RestoreInt09 ;πbeginπ   ExitProc := ExitSave ;π   SetIntVec( $09, OldInt09 ) ;πend ;ππ{$F+} Procedure NewInt09 ; interrupt ;πVarπ   ScanCode : Byte ;π   KeyCode : Byte ;πbeginπ   STI ;π   ScanCode := ReadScanCode ;π   KeyCode := ScanCode and $7F ;        { strip make/break bit }π   KeyTable[ KeyCode ] := ( ScanCode and $80 ) = 0 ; (* { For non C Programmersπ}π   if ( ScanCode and $80 ) = 0  then    { make code -- key pressed }π      KeyTable[ KeyCode ] := Trueπ   else                                 { break code -- key released }π      KeyTable[ KeyCode ] := False ;π*)π   ResetKeyboard ;π   EOI ;πend ;ππVarπ   N : Byte ;ππbeginπ   ExitSave := ExitProc ;π   ExitProc := addr( RestoreInt09 ) ;ππ   For N := 1 to 127 do            { no key pressed }π      KeyTable[ N ] := False ;ππ   GetIntVec( $09, OldInt09 ) ;π   SetIntVec( $09, addr( NewInt09 ) ) ;πend.π{---------------------------------------------} Program TwoKeys;ππUses Crt, Poll ;  { polled keyboard handler } { ----- this Program willπprobably hang a debugger ----- } Varπ   X, Y : Byte ;πbeginπ   ClrScr ;π   X := 40 ;π   Y := 12 ;ππ   WriteLn( 'Hit keys A S  and  1 2 on the keypad' ) ;π   WriteLn( ' -- Esc to stop' ) ;ππ   While not KeyTable[ EscKey ] doπ   beginπ      GotoXY( X, Y ) ;π      Write( ' ' ) ;ππ{ poll the KeyTable }π      if KeyTable[ endKey ] and ( X > 1 ) then  Dec( X ) ;π      if KeyTable[ DownKey ] and ( X < 80 ) then  Inc( X ) ;π      if KeyTable[ aKey ] and ( Y > 4 ) then  Dec( Y ) ;π      if KeyTable[ sKey ] and ( Y < 24 ) then  Inc( Y ) ;ππ      GotoXY( X, Y ) ;π      Write( chr( 1 ) ) ;π      Delay( 10 ) ;π   end ;πend.π                       4      05-28-9313:49ALL                      SWAG SUPPORT TEAM        INT09 Keyboard handler #2IMPORT              29          {πHere is my source For the keyboard handler.π}ππ{$X+}ππUnit KbIO;ππ(*---------------------------*) Interface (*----------------------------*)ππUses Dos;ππVarπ   KbScancode  : Byte;  { internal Variable, can be used by host Program }π   OldInt9Vect : Pointer;  { For storing the old interrupt vector }ππProcedure RestoreOldInt9;πProcedure NewInt9; Interrupt;ππ(*------------------------*) Implementation (*--------------------------*)ππProcedure RestoreOldInt9;  { Restores control to the old interrupt handler }πbeginπ  SetIntVec($09, OldInt9Vect);πend;ππ{$F+}πProcedure NewInt9; (* Interrupt; *)πVarπ  scancode : Byte;ππ  Procedure ResetKBD;π  Varπ    b : Byte;π  beginπ       b := Port[$61];π       Port[$61] := b or $80;π       Port[$61] := b;π       Port[$20] := $20;π  end;ππbeginπ  scancode   := Port[$60];π  KbScancode := scancode;π  (* at this point, you could add Up, Down, Left & Right Varsπ     eg. if (KbScancode = 72) then Up := True;π         if (KbScancode = 72 + 128) then Up := False;π         .π         .π         .π         Don't Forget to initialize Up, Down, etc. if you use them! *)π  ResetKBD;πend;π{$F-}ππbeginπ  GetIntVec($09, OldInt9Vect);π  SetIntVec($09, @NewInt9);π  KbScancode := 0;π  (*π    At this point, the Unit could install a custom Exit Procedureπ    that automatically restores the old keyboard handler when theπ    host Program finishes.π  *)πend.ππ{πJust include this Unit in your Uses clause, and, at any time during yourπProgram, you can check 'KbScancode' to see which key was currently pressed orπreleased.  Pressed keys have values between 0..127, and released keys have aπvalue between 128..255.  ESC = scancode #1, so here's a sample.π}πFunction Check4Quit : Boolean;πVarπ  kbcode  : Byte;π  tmpBool : Boolean;πbeginπ  tmpBool := False;π  kbcode := KbScancode;π  if (kbcode = 1) thenπ  beginππ     Repeatπ       kbcode := KbScancodeπ     Until (kbcode <> 1);π     (* the above line Repeats Until a different key is pressedπ        or released *)ππ     if (kbcode = 129) thenπ       tmpBool := True;π     (* if they released ESC directly after pressing it, withoutπ        pressing or releasing any other keys, return a True value *)ππ  end;π  Check4Quit := tmpBool;πend;ππ{πSo, basically, it's a good idea to save KbScancode in a temporary VariableπbeFore doing any checks on it, as it may change if you do this:ππif (KbScancode = 1) then beginπ   Delay(1);π   WriteLn('You pressed key #', KbScancode);πend;ππIn that short Delay, they may have released the key or pressed a new one,so theπvalue would have changed, and the Program might screw up.ππSomething to add:  Boolean Variables For Up, Down, Left, and Right, For use inπgames and such.  See the section in Procedure NewInt9.πππHey, Drew.  I Forgot one thing in my message about the custom KB handler.πYou'll probably receive this message at the same time as the Unit I sent.πHere is the important message:ππWhen using the KbIO Unit, at the very end of your Program, include the lineπthat restores the old int9 vector.  It is a Procedure called 'RestoreOldInt9'.πIt may not be Absolutely essential to include this line, but if you don'tπrestore the old keyboard handler, you might not be able to Type anything whenπthe Program Exits!  (not so good, huh?)  What to do: you can install a customπexit Procedure that restores the old int9 vector.  if you don't know how to doπthis, quote these lines, or Write to me about "custom Exit Procedures toπrestore the old int9 vector," or something like that.  Bye For now.π}π                                                                5      05-28-9313:49ALL                      SWAG SUPPORT TEAM        INT09 Keyboard handler #3IMPORT              30          {π>  Does anybody know of a way to reWrite the keyboard routines, to be ablπ>  to read several keys at once? ReadKey will only read the last keypressπ>  anything else I've tried can only read the last key you have pressed dπ>π>  For example, in many games it will let you move Forward (With the Forwπ>  arrow key) and shoot at the same time, With the space bar...Any suggesπOops, I Forgot to include one of the Units you'll need to do this. I've alreadyπsent you POLL.PAS and TWOKEYS.PAS.  Here's KEYinTR.PAS:π}πUnit KeyIntr ;  { support For inT 09 routines } { Turbo Pascal 5.5 } InterfaceπProcedure CLI ;  Inline( $FA ) ;   { disable interrupts } Procedure STI ;πInline( $FB ) ;   { enable interrupts } { cannot be used outside an interruptπProcedure } Procedure JumpInterrupt( p : Pointer ) ; { see TP5 Ref p 222π} Inline( $5B/$58/                         { POP  BX, AX   AX:BX = p }π        $89/$EC/                         { MOV  SP, BP             }π        $87/$46/$10/                     { XCHG AX, [BP+10H]       }π        $87/$5E/$0E/                     { XCHG BX, [BP+0EH]       }π        $5D/$07/$1F/$5F/$5E/             { POP  BP, ES, DS, DI, SI }π        $5A/$59/                         { POP  DX, CX             }π        $FA/                             { CLI                     }π        $CB ) ;                          { RETF          jmp Far p }ππFunction Control_Pressed : Boolean ;πProcedure EOI ;                         { end of interrupt to 8259 } FunctionπReadScanCode : Byte ;             { read keyboard } Procedure ResetKeyboard ;π               { prepare For next key } Procedure StoreKey( Scan, Key : Byte )π;π                                   { put key in buffer For inT 16 }πImplementation Uses Crt ;  { Sound, NoSound } Typeπ   Address = Record                  { used in Pointer manipulation }π                offset : Word ;π                Segment : Word ;π             end ;πConstπ   BiosDataSegment = $40 ;πVarπ   KeyState       : Word Absolute BiosDataSegment:$0017 ;π   KeyBufferHead  : Word Absolute BiosDataSegment:$001A ;π   KeyBufferTail  : Word Absolute BiosDataSegment:$001C ;π   KeyBufferStart : Word Absolute BiosDataSegment:$0080 ;π   KeyBufferend   : Word Absolute BiosDataSegment:$0082 ;πππFunction Control_Pressed : Boolean ;πbeginπControl_Pressed := ( KeyState and  4 ) = 4 ; end ;ππProcedure EOI ;  { end of interrupt to 8259 interrupt controller } beginπ   CLI ;π   Port[$20] := $20 ;     { see TP5 ref p 211 } end ;ππFunction ReadScanCode : Byte ;πbeginπReadScanCode := Port[$60] ;πend ;ππProcedure ResetKeyboard ;      { prepare For next key } Varπ   N : Byte ;πbeginπ   N := Port[$61] ;π   Port[$61] := ( N or $80 ) ;π   Port[$61] := N ;πend ;ππProcedure StoreKey( Scan, Key : Byte ) ; Var                { put key in bufferπthat inT 16 reads }π   P : ^Word ;π   N : Word ;πbeginπ   address(P).segment := BiosDataSegment ;π   N := KeyBufferTail ;π   address(P).offset := N ;π   Inc( N, 2 ) ;                      { advance Pointer two Bytes }π   if( N = KeyBufferend ) then        { end of the circular buffer }π      N := KeyBufferStart ;π   if( N = KeyBufferHead ) then       { buffer full }π   beginπ      EOI ;               { EOI must be done beFore Exit            }π      Sound( 2200 ) ;     {    but beFore anything that takes a lot }π      Delay( 80 ) ;       {     of time and can be interrupted      }π      NoSound ;π   endπ   elseπ   begin          { high Byte is scan code, low is ASCII }π      P^ := Scan * $100 + Key ;       { store key in circular buffer }π      KeyBufferTail := N ;            { advance tail Pointer }π      EOI ;π   end ;πend ;πend.π                                                                               6      05-28-9313:49ALL                      SWAG SUPPORT TEAM        Turn Keyboard OFF        IMPORT              15          {IDIOT PASCAL 101π----------------ππWelcome to IP 101. In today's lesson we will be answering a fewπoften asked questions about Turbo Pascal. if you signed up ForπIDIOT C/C++ 101, please get up and run beFore you get shot.ππQ:  HOW do I TURN ofF/ON THE KEYBOARD FROM MY Program?πA:  Easy. Though you may search through many books, you will findπ    the answer in a Excellent reference called _THE MS-Dosπ    ENCYCLOPEDIA_. It tells of a mystical I/O port where you canπ    turn off/on the keyboard by just flipping a bit. This port isπ    the 8259 Programmible Interrupt Controller. Now, part of theπ    8259 is the Interrupt Mask Register, or IMR For short. Theπ    port location is $21. to turn off the Keyboard...(RECKLESSLY)ππ}    Procedure KEYBOARD_ofF;ππ      beginπ        PorT[$21]:=$02π      end;π{π    to turn the keyboard back on (RECKLESSLY), just set the portπ    back to $0.ππ      (THE MSDos ENCYCLOPEDIA (C) 1988 Microsoft Press p417)ππQ: HOW do I FLIP BITS ON/ofF in A Byte or Integer?πA: Simple, Really.  The following Procedures work on bothπ   Byte,Char,Boolean,Integer, and Word values(I hope).π}πProcedure SBIT(Var TARGET;BITNUM:Integer);   {set bit}ππVarπ  SUBJECT : Integer Absolute TARGET;π  MASK    : Integer;ππ beginπ   MASK := 1 SHL BITNUM;π   SUBJECT := SUBJECT or MASKπ end;ππProcedure CBIT(Var TARGET;BITNUM:Integer);  {clear bit}ππ Varπ   SUBJECT : Integer Absolute TARGET;π   MASK    : Integer;ππ  beginπ    MASK := not(1 SHL BITNUM);π    SUBJECT := SUBJECT and MASKπ  end;ππProcedure SETBIT(Var TARGET;BITNUM:Integer;VALUE:Byte);{control}π                                                       {Proc.  }π beginπ   if VALUE = 1 thenπ     SBIT(TARGET,BITNUM)π   elseπ     CBIT(TARGET,BITNUM)π end;ππ                                                             7      05-28-9313:49ALL                      SWAG SUPPORT TEAM        Keyboard Handler         IMPORT              43          {π>     I need help on reading the keyboard in a specific way, I need toπ> read it as a whole not a key at a time. I need to do this forπ> the games I make, I have to ba able to hold down one key toπ> perform a Function and then hold down another key and scan bothπ> keys at the same time but to perform 2 different Functions. Forπ> instance, if I hold down the left arrow key to make a Characterπ> run I should be able to hold down the space bar to make himπ> fire a gun at the same time.π>     I would Really appreciate any help anyone could give me With this.ππGrab this (TWOKEYS.PAS) and the next 2 messages (KEYINTR.PAS and POLL.PAS).π}ππProgram TwoKeys;ππUsesπ  Crt, Poll ;  { polled keyboard handler }ππ{ ----- this Program will probably hang a debugger ----- }ππVarπ  X, Y : Byte ;ππbeginπ  ClrScr ;π  X := 40 ;π  Y := 12 ;ππ  WriteLn( 'Hit keys A S  and  1 2 on the keypad' ) ;π  WriteLn( ' -- Esc to stop' ) ;ππ  While not KeyTable[ EscKey ] doπ  beginπ    GotoXY( X, Y ) ;π    Write( ' ' ) ;ππ    { poll the KeyTable }π    If KeyTable[ endKey ] and ( X > 1 ) then  Dec( X ) ;π    If KeyTable[ DownKey ] and ( X < 80 ) then  Inc( X ) ;π    If KeyTable[ aKey ] and ( Y > 4 ) then  Dec( Y ) ;π    If KeyTable[ sKey ] and ( Y < 24 ) then  Inc( Y ) ;ππ    GotoXY( X, Y ) ;π    Write( chr( 1 ) ) ;π    Delay( 10 ) ;π  end ;πend.πππππUnit KeyIntr ;  { support For INT 09 routines }ππInterfaceππProcedure CLI ; Inline( $FA ) ; { disable interrupts }πProcedure STI ; Inline( $FB ) ; { enable interrupts }ππ{ cannot be used outside an interrupt Procedure }πProcedure JumpInterrupt( p : Pointer ) ;πInline(π  $5B/$58/                         { POP  BX, AX   AX:BX = p }π  $89/$EC/                         { MOV  SP, BP             }π  $87/$46/$10/                     { XCHG AX, [BP+10H]       }π  $87/$5E/$0E/                     { XCHG BX, [BP+0EH]       }π  $5D/$07/$1F/$5F/$5E/             { POP  BP, ES, DS, DI, SI }π  $5A/$59/                         { POP  DX, CX             }π  $FA/                             { CLI                     }π  $CB ) ;                          { RETF          jmp far p }πππFunction Control_Pressed : Boolean ;ππProcedure EOI ;π{ end of interrupt to 8259 }ππFunction ReadScanCode : Byte ;π{ read keyboard }ππProcedure ResetKeyboard ;π{ prepare For next key }ππProcedure StoreKey( Scan, Key : Byte );π{ put key in buffer For INT 16 }πππImplementationππUsesπ  Crt ;  { Sound, NoSound }ππTypeπ  Address = Record                  { used in Pointer manipulation }π    Offset : Word ;π    Segment : Word ;π  end ;πConstπ  BiosDataSegment = $40 ;ππVarπ  KeyState       : Word Absolute BiosDataSegment:$0017 ;π  KeyBufferHead  : Word Absolute BiosDataSegment:$001A ;π  KeyBufferTail  : Word Absolute BiosDataSegment:$001C ;π  KeyBufferStart : Word Absolute BiosDataSegment:$0080 ;π  KeyBufferend   : Word Absolute BiosDataSegment:$0082 ;πππFunction Control_Pressed : Boolean ;πbeginπ  Control_Pressed := ( KeyState and  4 ) = 4 ;πend;ππProcedure EOI ;π{ end of interrupt to 8259 interrupt controller }πbeginπ  CLI ;π  Port[$20] := $20 ;πend ;ππFunction ReadScanCode : Byte ;πbeginπ  ReadScanCode := Port[$60] ;πend ;ππProcedure ResetKeyboard ;π{ prepare For next key }πVarπ  N : Byte ;πbeginπ  N := Port[$61] ;π  Port[$61] := ( N or $80 ) ;π  Port[$61] := N ;πend ;ππProcedure StoreKey( Scan, Key : Byte ) ;πVarπ{ put key in buffer that INT 16 reads }π  P : ^Word ;π  N : Word ;πbeginπ  address(P).segment := BiosDataSegment ;π  N := KeyBufferTail ;π  address(P).offset := N ;π  Inc( N, 2 ) ;                      { advance Pointer two Bytes }π  If( N = KeyBufferend ) then        { end of the circular buffer }π     N := KeyBufferStart ;π  If( N = KeyBufferHead ) then       { buffer full }π  beginπ    EOI ;               { EOI must be done before Exit            }π    Sound( 2200 ) ;     {    but before anything that takes a lot }π    Delay( 80 ) ;       {     of time and can be interrupted      }π    NoSound ;π  endπ  Elseπ  begin          { high Byte is scan code, low is ASCII }π    P^ := Scan * $100 + Key ;       { store key in circular buffer }π    KeyBufferTail := N ;            { advance tail Pointer }π    EOI ;π  end ;πend ;ππend.πππππUnit POLL ;         { polled keyboard handler }π                    { does not support F11 or F12 keys } InterfaceππConstπ  EscKey = 1 ;    { key codes }π  aKey = 30 ;π  sKey = 31 ;π  endKey = 79 ;π  DownKey = 80 ;ππVarπ  KeyTable : Array[ 1..127 ] of Boolean ;ππ{ KeyTable[ x ] is True when key x is pressed and stays True Until keyπ  x is released }πππImplementationππUsesπ  Dos, KeyIntr ;  { keyboard interrupt support }ππVarπ  OldInt09 : Pointer ;π  ExitSave : Pointer ;ππProcedure RestoreInt09 ; Far;πbeginπ  ExitProc := ExitSave ;π  SetIntVec( $09, OldInt09 ) ;πend ;ππProcedure NewInt09 ; interrupt ; Far;πVarπ  ScanCode : Byte ;π  KeyCode : Byte ;πbeginπ  STI ;π  ScanCode := ReadScanCode ;π  KeyCode := ScanCode and $7F ;        { strip make/break bit }π  KeyTable[ KeyCode ] := ( ScanCode and $80 ) = 0 ;π  ResetKeyboard ;π  EOI ;πend ;ππVarπ  N : Byte ;ππbeginπ  ExitSave := ExitProc ;π  ExitProc := addr( RestoreInt09 ) ;ππ  For N := 1 to 127 do   { no key pressed }π    KeyTable[ N ] := False ;ππ  GetIntVec( $09, OldInt09 ) ;π  SetIntVec( $09, addr( NewInt09 ) ) ;πend.π                                                                                                            8      05-28-9313:49ALL                      SWAG SUPPORT TEAM        Get Keyboard CLICK       IMPORT              8           {$M $800,0,0 }   { 2K stack, no heap }π{ This Program caUses a click each timeπ a key is pressed.}πUses Crt, Dos;πVarπ  KbdIntVec : Procedure;π{$F+}πProcedure Keyclick; interrupt;πbeginπ  if Port[$60] < $80 thenπ    { Only click when key is pressed }π    beginπ    Sound(5000);π    Delay(1);π    NoSound;π    end;π  Inline ($9C); { PUSHF -- Push flags }π  { Call old ISR using saved vector }π  KbdIntVec;πend;π{$F-}πbeginπ  { Insert ISR into keyboard chain }π  GetIntVec($9,@KbdIntVec);π  SetIntVec($9,Addr(Keyclick));π  Keep(0); { Terminate, stay resident }π  readln;πend.ππ{πActually this works as long as you change the GETinTVEC line, where it saysπ@@KbdIntVec, it should be only one @, odd that borland would have an exampleπthat didn't Compile. (It's a fine example, surprised myself too)π}                                                                                                    9      05-28-9313:49ALL                      SWAG SUPPORT TEAM        Int 09 Support           IMPORT              22          UNIT KeyIntr ;  { support for INT 09 16 routines } { Turbo Pascal 5.5+ }ππINTERFACEππTypeπ   InterruptProcedure = Procedure ;ππConstπ   BiosDataSegment = $40 ;ππProcedure DisableInterrupts ; Inline( $FA ) ;   { CLI }πProcedure EnableInterrupts ;  Inline( $FB ) ;   { STI }πProcedure CallInterrupt( P : Pointer ) ;ππFunction AltPressed : Boolean ;πFunction ControlPressed : Boolean ;πFunction ShiftPressed : Boolean ;ππProcedure EOI ;                      { end of interrupt to 8259 }πFunction ReadScanCode : Byte ;       { read keyboard }πProcedure ResetKeyboard ;            { prepare for next key }π                                     { put key in buffer for INT 16 }πFunction StoreKey( Scan, Key : Byte ) : Boolean ;ππIMPLEMENTATIONππTypeπ   TwoBytesPtr = ^TwoBytes ;π   TwoBytes =               { one key in the keyboard buffer }π   Recordπ      KeyCode,π      ScanCode : Byte ;π   End ;ππVarπ   KeyState       : Word Absolute BiosDataSegment:$17 ;π   KeyBufferHead  : Word Absolute BiosDataSegment:$1A ;π   KeyBufferTail  : Word Absolute BiosDataSegment:$1C ;π   KeyBufferStart : Word Absolute BiosDataSegment:$80 ;π   KeyBufferEnd   : Word Absolute BiosDataSegment:$82 ;ππProcedure CallInterrupt( P : Pointer ) ;πBeginπ   Inline( $9C ) ;       { PUSHF }π   InterruptProcedure(P) ;πEnd ;ππFunction AltPressed : Boolean ;πBeginπ   AltPressed := (KeyState and 8) <> 0 ;πEnd ;ππFunction ControlPressed : Boolean ;πBeginπ   ControlPressed := (KeyState and 4) <> 0 ;πEnd ;ππFunction ShiftPressed : Boolean ;πBeginπ   ShiftPressed := (KeyState and 3) <> 0 ;πEnd ;ππProcedure EOI ;  { end of interrupt to 8259 interrupt controller }πBeginπ   Port[$20] := $20 ;πEnd ;ππFunction ReadScanCode : Byte ;πVarπ   N : Byte ;πBeginπ   N := Port[$60] ;     { $FF means keyboard overrun }π   ReadScanCode := N ;πEnd ;ππProcedure ResetKeyboard ;      { prepare for next key }πVarπ   N : Byte ;πBeginπ   N := Port[$61] ;π   Port[$61] := (N or $80) ;π   Port[$61] := N ;πEnd ;ππFunction StoreKey( Scan, Key : Byte ) : Boolean ;πVar                { put key in buffer that INT 16 reads }π   P : TwoBytesPtr ;π   N : Word ;πBeginπ   DisableInterrupts ;ππ   N := KeyBufferTail ;π   P := Ptr( BiosDataSegment, N ) ;ππ   Inc( N, 2 ) ;π   If( N = KeyBufferEnd ) then        { end of the circular buffer }π      N := KeyBufferStart ;π   If( N = KeyBufferHead ) then       { buffer full }π   Beginπ      EnableInterrupts ;π      StoreKey := False ;π   Endπ   Elseπ   Beginπ      P^.KeyCode := Key ;π      P^.ScanCode := Scan ;             { store key in circular buffer }π      KeyBufferTail := N ;              { advance tail pointer }π      EnableInterrupts ;π      StoreKey := True ;π   End ;πEnd ;πππEND.ππππ  10     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Keyboard SCAN Keys       IMPORT              28          {π> I need help on reading the keyboard in a specific way, I need to read itπ>as a whole not a key at a time. I need to do this For the games I make, Ihaπ>to ba able to hold down one key to perform a Function and then hold downπ>another key and scan both keys at the same time but to perform 2 differentπ>Functions. For instance, if I hold down the left arrow key to make aCharactπ>run I should be able to hold down the space bar to make him fire agun at thπ>same time.ππ by Sean Palmer, 1993, released to public domainπ}ππUnit keyScan;  {for now, ignores extended codes ($E0 prefix)}ππInterfaceππTypeπ  scanCode = (π    kNone, kEsc, k1, k2, k3, k4, k5, k6, k7, k8, k9, k0, kMinus, kEqual,π    kBack, kTab, kQ, kW, kE, kR, kT, kY, kU, kI, kO, kP, kLBracket,π    kRBracket, kEnter, kCtrl, kA, kS, kD, kF, kG, kH, kJ, kK, kL, kColon,π    kQuote, kTilde, kLShift, kBackSlash, kZ, kX, kC, kV, kB, kN, kM, kComma,π    kPeriod, kSlash, kRShift, kPadStar, kAlt, kSpace, kCaps, kF1, kF2, kF3,π    kF4, kF5, kF6, kF7, kF8, kF9, kF10, kNum, kScroll, kHome, kUp, kPgUp,π    kPadMinus, kLf, kPad5, kRt, kPadPlus, kend, kDn, kPgDn, kIns, kDel,π    kSysReq, kUnknown55, kUnknown56, kF11, kF12);ππConstπ  kPad7 = kHome;π  kPad8 = kUp;π  kPad9 = kPgUp;π  kPad4 = kLf;π  kPad6 = kRt;π  kPad1 = kend;π  kPad2 = kDn;π  kPad3 = kPgDn;π  letters = [kQ..kP, kA..kL, kZ..kM];π  numbers = [k1..k0, kPad1..kPad3, kPad4..kPad6, kPad7..kPad9];π  FunctionKeys = [kF1..kF10, kF11..kF12];π  keyPad = [kPadStar, kNum..kDel];ππVarπ keyboard : set of scanCode;π lastKeyDown : scanCode;ππImplementationπUses Dos;ππConstπ  normChar : Array [scanCode] of Char = (π  {00} #0,^[,'1','2','3','4','5','6','7','8','9','0','-','=',^H,^I,π  {10} 'q','w','e','r','t','y','u','i','o','p','[',']',^M,#0,'a','s',π  {20} 'd','f','g','h','j','k','l',';','''','`',#0,'\','z','x','c','v',π  {30} 'b','n','m',',','.','/',#0,'*',#0,' ',#0,#0,#0,#0,#0,#0,π  {40} #0,#0,#0,#0,#0,#0,#0,'7','8','9','-','4','5','6','+','1',π  {50} '2','3','0','.',#0,#0,#0,#0,#0);π  shiftChar : Array [scanCode] of Char = (π  {00} #0,^[,'!','@','#','$','%','^','&','*','(',')','_','+',^H,^I,π  {10} 'Q','W','E','R','T','Y','U','I','O','P','{','}',^M,#0,'A','S',π  {20} 'D','F','G','H','J','K','L',':','"','~',#0,'|','Z','X','C','V',π  {30} 'B','N','M','<','>','?',#0,'*',#0,' ',#0,#0,#0,#0,#0,#0,π  {40} #0,#0,#0,#0,#0,#0,#0,'7','8','9','-','4','5','6','+','1',π  {50} '2','3','0','.',#0,#0,#0,#0,#0);ππFunction ascii(k : scanCode) : Char;πbeginπ  if [kLShift, kRShift] * keyboard <> [] thenπ    ascii := shiftChar[k]π  elseπ    ascii := normChar[k];πend;ππVarπ  oldKeyInt : Pointer;ππProcedure keyISR; interrupt;πVarπ  k : scanCode;π  b : Byte;πbeginπ  Asmπ   in al, $60;π   mov b, al;π   and al, $7F;π   mov k, al;π   pushF;π   call [oldKeyInt];      {allow BIOS to process also}π  end;π  memW[$40 : $1A] := memW[$40 : $1C];  {clear BIOS keyboard buffer}π  if shortint(b) >= 0 thenπ  beginπ    keyboard := keyboard + [k];π    lastKeyDown := k;π  endπ  elseπ  if b <> $E0 thenπ    keyboard := keyboard - [k]π  else ;πend;ππProcedure keybegin;πbeginπ  keyboard := [];π  lastKeyDown := kNone;π  getIntVec(9, oldKeyInt);π  setIntVec(9, @KeyISR);πend;ππVarπ  ExitSave:Pointer;ππProcedure keyend;πbeginπ  setIntVec(9, oldKeyInt);π  ExitProc := ExitSave;πend;πππbeginπ  keybegin;π  ExitSave := ExitProc;π  ExitProc := @keyend;πend.π                                                                                                       11     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Lock Keyboard            IMPORT              14          {$X+}ππ{ Author Trevor J Carlsen.  Released into the public domain. Req TP6   }π{ Compile and run this Program and all keyboard input except keys that }π{ make up a valid passWord will be ignored.  In this Case the passWord }π{ is '1234' and the scancodes For those keys are stored in a Constant. }π{ to change the passWord Compute the scancodes For the desired passWord}π{ and change the passWord approriately.                                }ππUsesπ  Dos,π  Crt;ππVarπ  OldInt9       : Pointer;   { For storing the old interrupt vector }π  passWord      : String[4];π  pwdlen        : Byte Absolute passWord;π  πProcedure RestoreOldInt9;π  { Restores control to the old interrupt handler }π  beginπ    SetIntVec($09,OldInt9);π  end;ππ{$F+}πProcedure NewInt9; interrupt;π π  Constπ    masterpwd :String[4] = #2#3#4#5;  { '1234' scancodes }π  Var π    scancode  : Byte;ππ  Procedure ResetKBD;π    Varπ       b : Byte;π    beginπ       b := port[$61]; π       port[$61] := b or $80;π       port[$61] := b;π       port[$20] := $20; { Signals EOI to PIC }π    end;π  πbeginπ  scancode    := port[$60]; π  if chr(scancode)  = masterpwd[pwdlen+1] then beginπ    passWord[pwdlen+1]  := chr(scancode);π    inc(pwdlen);π    if passWord = masterpwd thenπ      RestoreOldInt9;π  endπ  else if not odd(scancode shr 7) then { invalid key }π    pwdlen := 0;π  ResetKBD;πend; π{$F-}ππbeginπ  pwdlen := 0;π  GetIntVec($09,OldInt9);π  SetIntVec($09,@NewInt9);π  ReadKey;πend.  π π     πππTeeCeeπππ--- TC-ED   v2.01  π * origin: The Pilbara's Pascal Centre (+61 91 732569) (3:690/644)ππ                                                                                               12     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Read CTRL/ALT/SHIFT Keys IMPORT              11          {π> I was sitting here thinking about how usefull it would be to be ableπ> to check the status of the different Locks (eg. scroll lock, num lockπ> or how to do it.  I think it is some sort of Bios or Dos service??π> Any help would be greatly appreciated.ππThe easiest way is to access BIOS memory at address 40h:17hππ}πProcedure TestKeys;ππVarπ  Scroll_Lock,π  Caps_Lock,π  Num_Lock,π  Ins,π  Alt,π  Ctrl,π  Left_Shift,π  Right_Shift : Boolean;π  Bios_Keys   : Byte Absolute $40:$17;ππbeginπ  Ins           := ((Bios_Keys And $80) = $80);π  Caps_Lock     := ((Bios_Keys And $40) = $40);π  Num_Lock      := ((Bios_Keys And $20) = $20);π  Scroll_Lock   := ((Bios_Keys And $10) = $10);π  Alt           := ((Bios_Keys And $8)  = $8);π  Ctrl          := ((Bios_Keys And $4)  = $4);π  Left_Shift    := ((Bios_Keys And $2)  = $2);π  Right_Shift   := ((Bios_Keys And $1)  = $1);ππ  Writeln('Insert      : ', Ins);π  Writeln('CapsLock    : ', Caps_Lock);π  Writeln('NumLock     : ', Num_Lock);π  Writeln('ScrollLock  : ', Scroll_Lock);π  Writeln('Alt         : ', Alt);π  Writeln('Control     : ', Ctrl);π  Writeln('Left Shift  : ', Left_Shift);π  Writeln('Right Shift : ', Right_Shift);πend;ππbeginπ  TestKeys;π  Readln;πend.                                                               13     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Read CTL/ALT/SHIFT #2    IMPORT              8           Uses Dos;πVarπ    regs :  Registers;π    stat :  Byte;π    inse, caps, numl, scrll, alt, ctrl, lshift, rshift : Boolean;π    { declaration of all the bools hidden :) }πbeginπ     regs.ah:=2; intr($16,regs);π     stat:=regs.al;ππ     inSE   := stat and 128 <> 0;   { Insert on    }π     CAPS   := stat and  64 <> 0;   { CapsLock     }π     NUML   := stat and  32 <> 0;   { NumLock      }π     SCRLL  := stat and  16 <> 0;   { ScrolLock    }π     ALT    := stat and   8 <> 0;   { ALT pressed  }π     CTRL   := stat and   4 <> 0;   { CTRL pressed }π     LSHifT := stat and   2 <> 0;   { left Shift " }π     RSHifT := stat and   1 <> 0;   { right Shift" }ππ     Writeln(inSE);π     Writeln(CAPS);π     Writeln(NUML);π     Writeln(SCRLL);π     Writeln(ALT);π     Writeln(CTRL);π     Writeln(LSHifT);π     Writeln(RSHifT);πend.π                                                                          14     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Read Keyboard STATE Keys IMPORT              17          {π>Can someone give me some code to make the lights Num lock/capsπ>lock/scroll lock keys to turn on?π}ππProgram KeySet;πConstπ  CapsState   = $40; { Mask For Caps Lock state }π  NumState    = $20; { Mask For Num Lock state }π  ScrollState = $10; { Mask For Scroll Lock state }πVarπ  Kb : Byte Absolute $0040:$0017; { Address of keyboard flags }π  I  : Byte;π  S  : String;πbeginπ  if ParamCount = 0 thenπ  beginπ    WriteLn;π    WriteLn(' Command line options:');π    WriteLn;π    WriteLn(' C toggle Cap lock state');π    WriteLn(' N toggle Num lock state');π    WriteLn(' S toggle Scroll lock state');π    WriteLn(' Add + to turn on and - to turn off');π    Halt(1);π  end;π  For I := 1 to ParamCount Doπ  beginπ    S := ParamStr(I);π    S[1] := UpCase(S[1]);π    { toggle Caps Lock }π    if S = 'C' then Kb := Kb xor CapsState;π    { toggle Num Lock }π    if S = 'N' then Kb := Kb xor NumState;π    { toggle Scroll Lock }π    if S = 'S' then Kb := Kb xor ScrollState;π    { Set Caps Lock on }π    if S = 'C+' then Kb := Kb or CapsState;π    { Set Num Lock on }π    if S = 'N+' then Kb := Kb or NumState;π    { Set Scroll Lock on }π    if S = 'S+' then Kb := Kb or ScrollState;π    { Set Caps Lock off }π    if S = 'C-' then Kb := Kb and not (CapsState or not Kb);π    { Set Num Lock off }π    if S = 'N-' then Kb := Kb and not (NumState or not Kb);π    { Set Scroll Lock off }π    if S = 'S-' then Kb := Kb and not (ScrollState or not Kb);π  end;ππ  Write('Caps Lock  : ');π  if (Kb and CapsState) = CapsState thenπ    WriteLn('ON')π  elseπ    WriteLn('ofF');ππ  Write('Num Lock   : ');π  if (Kb and NumState) = NumState thenπ    WriteLn('ON')π  elseπ    WriteLn('ofF');ππ  Write('Scroll Lock: ');π  if (Kb and ScrollState) = ScrollState thenπ    WriteLn('ON')π  elseπ    WriteLn('ofF');πend.ππ{πThis Program will toggle, Turn on, or Turn off the Caps Lock, NumπLock, and Scroll Lock lights. and when its done it tells you theπstate of each key.π}π                                                                                                  15     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Keyboard SCAN Keys       IMPORT              86          {AM▒Hi everyone, I have a question. I need to know if there is some simpleπAM▒way to do the following. I want to pass as a parameter to a ProcedureπAM▒that will indicate what keypresses are valid. I am doing this alreadyπAM▒for regular keys, but I need to be able to list regular keys as well asπAM▒extended key(mostly Function keys).ππAM▒I do like so,ππAM▒Command_Keys : Set of Char ['Q', 'A', 'K'];πAM▒Is there a way to add extended keys to the above.ππDeclare extended scan codes, then format them into an Array:π}πConstππ(* Function keys *)π    F1 = $3B00;       ShF1 = $5400;      CtrlF1 = $5E00;      AltF1 = $6800;π    F2 = $3C00;       ShF2 = $5500;      CtrlF2 = $5F00;      AltF2 = $6900;π    F3 = $3D00;       ShF3 = $5600;      CtrlF3 = $6000;      AltF3 = $6A00;π    F4 = $3E00;       ShF4 = $5700;      CtrlF4 = $6100;      AltF4 = $6B00;π    F5 = $3F00;       ShF5 = $5800;      CtrlF5 = $6200;      AltF5 = $6C00;π    F6 = $4000;       ShF6 = $5900;      CtrlF6 = $6300;      AltF6 = $6D00;π    F7 = $4100;       ShF7 = $5A00;      CtrlF7 = $6400;      AltF7 = $6E00;π    F8 = $4200;       ShF8 = $5B00;      CtrlF8 = $6500;      AltF8 = $6F00;π    F9 = $4300;       ShF9 = $5C00;      CtrlF9 = $6600;      AltF9 = $7000;π   F10 = $4400;      ShF10 = $5D00;     CtrlF10 = $6700;     AltF10 = $7100;π   F11 = $8500;      ShF11 = $8700;     CtrlF11 = $8900;     AltF11 = $8B00;π   F12 = $8600;      ShF12 = $8800;     CtrlF12 = $8A00;     AltF12 = $8C00;ππ(* Numeric keypad *)π    Up = $4800;       ShUp = $4838;      CtrlUp = $8D00;      AltUp = $9800;π  Down = $5000;     ShDown = $5032;    CtrlDown = $9100;    AltDown = $A000;π  Left = $4B00;     ShLeft = $4B34;    CtrlLeft = $7300;    AltLeft = $9B00;π Right = $4D00;    ShRight = $4D36;   CtrlRight = $7400;   AltRight = $9D00;π  Home = $4700;     ShHome = $4737;    CtrlHome = $7700;    AltHome = $9700;πendKey = $4F00;      Shend = $4F31;     Ctrlend = $7500;     Altend = $9F00;π  PgUp = $4900;     ShPgUp = $4939;    CtrlPgUp = $8400;    AltPgUp = $9900;π  PgDn = $5100;     ShPgDn = $5133;    CtrlPgDn = $7600;    AltPgDn = $A100;π   Ins = $5200;      ShIns = $5230;     CtrlIns = $9200;     AltIns = $A200;π   Del = $5300;      ShDel = $532E;     CtrlDel = $9300;     AltDel = $A300;π  Pad5 = $4C00;     ShPad5 = $4C35;    CtrlPad5 = $8F00;    AltPad5 = $9C00;ππ(* Alphabetic keys *)π  LowA = $1E61;        UpA = $1E41;       CtrlA = $1E01;       AltA = $1E00;π  LowB = $3062;        UpB = $3042;       CtrlB = $3002;       AltB = $3000;π  LowC = $2E63;        UpC = $2E43;       CtrlC = $2E03;       AltC = $2E00;π  LowD = $2064;        UpD = $2044;       CtrlD = $2004;       AltD = $2000;π  LowE = $1265;        UpE = $1245;       CtrlE = $1205;       AltE = $1200;π  LowF = $2166;        UpF = $2146;       CtrlF = $2106;       AltF = $2100;π  LowG = $2267;        UpG = $2247;       CtrlG = $2207;       AltG = $2200;π  LowH = $2368;        UpH = $2348;       CtrlH = $2308;       AltH = $2300;π  LowI = $1769;        UpI = $1749;       CtrlI = $1709;       AltI = $1700;π  LowJ = $246A;        UpJ = $244A;       CtrlJ = $240A;       AltJ = $2400;π  LowK = $256B;        UpK = $254B;       CtrlK = $250B;       AltK = $2500;π  LowL = $266C;        UpL = $264C;       CtrlL = $260C;       AltL = $2600;π  LowM = $326D;        UpM = $324D;       CtrlM = $320D;       AltM = $3200;π  LowN = $316E;        UpN = $314E;       CtrlN = $310E;       AltN = $3100;π  LowO = $186F;        UpO = $184F;       CtrlO = $180F;       AltO = $1800;π  LowP = $1970;        UpP = $1950;       CtrlP = $1910;       AltP = $1900;π  LowQ = $1071;        UpQ = $1051;       CtrlQ = $1011;       AltQ = $1000;π  LowR = $1372;        UpR = $1352;       CtrlR = $1312;       AltR = $1300;π  LowS = $1F73;        UpS = $1F53;       CtrlS = $1F13;       AltS = $1F00;π  LowT = $1474;        UpT = $1454;       CtrlT = $1414;       AltT = $1400;π  LowU = $1675;        UpU = $1655;       CtrlU = $1615;       AltU = $1600;π  LowV = $2F76;        UpV = $2F56;       CtrlV = $2F16;       AltV = $2F00;π  LowW = $1177;        UpW = $1157;       CtrlW = $1117;       AltW = $1100;π  LowX = $2D78;        UpX = $2D58;       CtrlX = $2D18;       AltX = $2D00;π  LowY = $1579;        UpY = $1559;       CtrlY = $1519;       AltY = $1500;π  LowZ = $2C7A;        UpZ = $2C5A;       CtrlZ = $2C1A;       AltZ = $2C00;ππ(* Number keys, on top row of keyboard *)π  Num1 = $0231;                                                Alt1 = $7800;π  Num2 = $0332;                           Ctrl2 = $0300;       Alt2 = $7900;π  Num3 = $0433;                                                Alt3 = $7A00;π  Num4 = $0534;                                                Alt4 = $7B00;π  Num5 = $0635;                                                Alt5 = $7C00;π  Num6 = $0736;                           Ctrl6 = $071E;       Alt6 = $7D00;π  Num7 = $0837;                                                Alt7 = $7E00;π  Num8 = $0938;                                                Alt8 = $7F00;π  Num9 = $0A39;                                                Alt9 = $8000;π  Num0 = $0B30;                                                Alt0 = $8100;ππ(* Miscellaneous *)π   Space = $3920;π    BkSp = $0E08;                   CtrlBkSp = $0E7F;       AltBkSp = $0E00;π     Tab = $0F09;   ShTab = $0F00;  CtrlTab  = $9400;        AltTab = $A500;π   Enter = $1C0D;                   CtrlEnter= $1C0A;      AltEnter = $1C00;π     Esc = $011B;                                            AltEsc = $0100;ππ   Minus = $0C2D;                  CtrlMinus = $0C1F;      AltMinus = $8200;π                     Plus = $0D2B;                          AltPlus = $8300;πPadMinus = $4A2D;               CtrlPadMinus = $8E00;    AltPadMinus= $4A00;π PadPlus = $4E2B;                CtrlPadPlus = $9000;    AltPadPlus = $4E00;π                     Star = $092A;π PadStar = $372A;                                        AltPadStar = $3700;ππ{AM>I do like so,πAM>Command_Keys : Set of Char ['Q', 'A', 'K'];π  >Is there a way to add extended keys to the above.ππ  Hi Andrew!π  One painless way is to set the high bit For Function keys.π}πUses Crt;πConstπ  Home   = #199;      UArr  = #200;     PgUp  = #201;π  LArr   = #203;      Five  = #204;     RArr  = #205;π  endkey = #207;      DArr  = #208;     PgDn  = #209;π  Ins   = #210;       Del   = #211;ππ  CtrlHome = #247;    CtrlUP   = #141;    CtrlPgUp = #138;π  CtrlLArr = #243;    CtrlFive = #143;    CtrlRArr = #244;π  Ctrlend  = #245;    CtrlDown = #145;    CtrlPgDn = #246;π  CtrlIns  = #146;    CtrlDel  = #147;ππ  BackSp  = #8;π  Tab     = #9;       STab    = #143;π  Enter   = #13;π  Esc     = #27;ππ  CtrlPrtsc = #242;ππ  CtrlA  = #1;     AltA  = #158;        Alt1 = #248;π  CtrlB  = #2;     AltB  = #176;        Alt2 = #249;π  CtrlC  = #3;     AltC  = #174;        Alt3 = #250;π  CtrlD  = #4;     AltD  = #160;        Alt4 = #251;π  CtrlE  = #5;     AltE  = #146;        Alt5 = #252;π  CtrlF  = #6;     AltF  = #161;        Alt6 = #253;π  CtrlG  = #7;     AltG  = #162;        Alt7 = #254;π  CtrlH  = #8;     AltH  = #163;        Alt8 = #255;π  CtrlI  = #9;     AltI  = #151;        Alt9 = #134;π  CtrlJ  = #10;    AltJ  = #164;        Alt0 = #135;π  CtrlK  = #11;    AltK  = #165;        Altminus  = #136;π  CtrlL  = #12;    AltL  = #166;        Altequals = #137;π  CtrlM  = #13;    AltM  = #178;π  CtrlN  = #14;    AltN  = #177;π  CtrlO  = #15;    AltO  = #152;π  CtrlP  = #16;    AltP  = #153;π  CtrlQ  = #17;    AltQ  = #144;π  CtrlR  = #18;    AltR  = #147;π  CtrlS  = #19;    AltS  = #159;π  CtrlT  = #20;    AltT  = #148;π  CtrlU  = #21;    AltU  = #150;π  CtrlV  = #22;    AltV  = #175;π  CtrlW  = #23;    AltW  = #145;π  CtrlX  = #24;    AltX  = #173;π  CtrlY  = #25;    AltY  = #149;π  CtrlZ  = #26;    AltZ  = #172;ππ  F1  = #187;      sF1  = #212;      CtrlF1  = #222;      AltF1  = #232;π  F2  = #188;      sF2  = #213;      CtrlF2  = #223;      AltF2  = #233;π  F3  = #189;      sF3  = #214;      CtrlF3  = #224;      AltF3  = #234;π  F4  = #190;      sF4  = #215;      CtrlF4  = #225;      AltF4  = #235;π  F5  = #191;      sF5  = #216;      CtrlF5  = #226;      AltF5  = #236;π  F6  = #192;      sF6  = #217;      CtrlF6  = #227;      AltF6  = #237;π  F7  = #193;      sF7  = #218;      CtrlF7  = #228;      AltF7  = #238;π  F8  = #194;      sF8  = #219;      CtrlF8  = #229;      AltF8  = #239;π  F9  = #195;      sF9  = #220;      CtrlF9  = #230;      AltF9  = #240;π  F10 = #196;      sF10 = #221;      CtrlF10 = #231;      AltF10 = #241;π  F11 = #139;      sF11 = #141;      CtrlF11 = #154;      AltF11 = #156;π  F12 = #140;      sF12 = #142;      CtrlF12 = #155;      AltF12 = #157;ππ  Key  : Char = #0;ππVarπ  NextOn        : ^Word Absolute $0040:$001A;    {keyboard buffer}π  NextOff       : ^Word Absolute $0040:$001C;    {keyboard buffer}π  KeyStatusBits : Word    Absolute $0040:$0017;  {keyboard buffer}π  KeyStatus : Recordπ     RShift, LShift,π     RCtrl,  LCtrl,π     RAlt,   LAlt,π     Caps,   CapsON,π     Ins,    InsON,π     Scroll, ScrlON,π     Num,    NumON          : Boolean;π  end;ππProcedure GetKeyStatus;   { Changes KeyStatus Variable }πConst Old : Word = 0;πbeginπ  Old := KeyStatusBits;π  FillChar(KeyStatus,SizeOf(KeyStatus),0);π  With KeyStatus doπ  beginπ   RShift := ((Old Shr 0 ) and 1) = 1;π   LShift := ((Old Shr 1 ) and 1) = 1;π   RCtrl  := ((Old Shr 2 ) and 1) = 1;  { Test For either CTRL Key }π   RAlt   := ((Old Shr 3 ) and 1) = 1;  { Test For either Alt Key }π   ScrlON := ((Old Shr 4 ) and 1) = 1;  { Is Scroll Lock light on }π   NumON  := ((Old Shr 5 ) and 1) = 1;  { Is Num Lock light on }π   CapsON := ((Old Shr 6 ) and 1) = 1;  { Is Caps Lock light on }π   InsON  := ((Old Shr 7 ) and 1) = 1;  { Is Insert State on }π   LCtrl  := ((Old Shr 8 ) and 1) = 1;  { This also sets bit 3 }π   LAlt   := ((Old Shr 9 ) and 1) = 1;  { This also sets bit 4 }π   Scroll := ((Old Shr 12) and 1) = 1;  { This toggles bit 5 }π   Num    := ((Old Shr 13) and 1) = 1;  { This toggles bit 6 }π   Caps   := ((Old Shr 14) and 1) = 1;  { This toggles bit 7 }π   Ins    := ((Old Shr 15) and 1) = 1;  { This toggles bit 8 }π  end;πend; { }ππFunction GetKey : Char;πbeginπ  If KeyPressed then         { Test For BIOS key pressed }π   beginπ     Key := ReadKey;          { Basic BIOS Keyboard Entry }π     if Key = #0 thenπ     beginπ       Key := ReadKey;π       Inc(Key,128);          { Make Expanded key codes one Byte }π     end; { }π   end else Key := #0;π   GetKey := Key;πend; { }ππProcedure FlushBuffer;πbeginπ  Move(NextOn,NextOff,SizeOf(NextOn));πend; { }ππVar test : Char ;πbeginπ  ClrScr;π  WriteLN('Press Both Shift Keys to end');π  Repeatπ    GetKeyStatus;π    Test := GetKey;π    if Test <> #0 Then Write(Test);ππ  Until (KeyStatus.RShift and KeyStatus.LShift);πend.π                                                                                                     16     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Keyboard SCAN Codes      IMPORT              16          {πROBERT ROTHENBURGππ>I have created a Menu Bar, Now I think key #77 is left and key #77 isπ>assigned to "M" or one of them. But anyway so when someone pushes theπ>"M" key the menu bar moves. So how can I stop this, I only want it toπ>use the arrow keys and a few letters but not "M".ππYou guessed it: USE BIOS CALLS!π}ππProgram ShowCodes; {* This Program will output the keyboardπ                   {* scan codes.  Use the Function "ScanCode"π                   {* in your Program once you know the codesπ                   {* For each keypress *}πUsesπ  Crt, Dos;ππFunction Byte2Hex(numb : Byte): String;       { Converts Byte to hex String }πConstπ  HexChars : Array[0..15] of Char = '0123456789ABCDEF';πbeginπ  Byte2Hex[0] := #2;π  Byte2Hex[1] := HexChars[numb shr  4];π  Byte2Hex[2] := HexChars[numb and 15];πend; { Byte2Hex }ππFunction Numb2Hex(numb : Word): String;        { Converts Word to hex String.}πbeginπ  Numb2Hex := Byte2Hex(hi(numb)) + Byte2Hex(lo(numb));πend; { Numb2Hex }ππFunction ScanCode : Word;πVarπ  reg : Registers;    {* You need the Dos Unit For this! *}πbeginπ  reg.AH := $10;      {* This should WAIT For a keystroke.  Ifπ                      {* you'd like to POLL For a keystroke andπ                      {* have your Program do other stuff Whileπ                      {* "waiting" For a key-stroke change toπ                      {* reg.AH:=$11 instead... *}π  intr($16, reg);π  ScanCode := reg.AX  {* The high-Byte is the "scan code" *}πend;                  {* The low-Byte is the ASCII Character *}ππbeginπ  Repeatπ    Writeln(Numb2Hex(ScanCode) : 6)π  Until False;        {* You'll have to reboot after running this <g>*}πend.ππ{πI "think" the arrow-key scan codes are:ππ   $4800 = Up Arrowπ   $5000 = Down Arrowπ   $4B00 = Left Arrowπ   $4D00 = Right Arrowπ}π                                                                                                                           17     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Display MAKE/BREAK codes IMPORT              14          PROGRAM ScanCode ;      { display MAKE and BREAK scan codes }ππUSES Crt, Dos, KeyIntr ;      { keyboard interrupt support }ππ{ ----- this program will probably hang a debugger ----- }ππVarπ   OldInt09 : Pointer ;π   ExitSave : Pointer ;ππ{$F+} Procedure RestoreInt09 ;πBeginπ   ExitProc := ExitSave ;π   SetIntVec( $09, OldInt09 ) ;πEnd ;ππ{$F+} Procedure NewInt09 ; Interrupt ;   { return scan code as key's value }πVarπ   ScanCode : Byte ;π   BufferFull : Boolean ;ππBeginπ   EnableInterrupts ;π   ScanCode := ReadScanCode ;π   ResetKeyboard ;π   BufferFull := Not StoreKey( ScanCode, ScanCode ) ;π   EOI ;π   If BufferFull thenπ   Beginπ      Sound( 880 ) ;π      Delay( 100 ) ;π      Sound( 440 ) ;π      Delay( 100 ) ;π      NoSound ;π   End ;π                { variation : move the EOI before the beep to after it }π                {      note the difference when the keyboard overflows }πEnd ;ππ{ see Turbo Pascal 5.0 reference p 450 for a list of scan codes }π{                  6.0 programmers guide p 354                  }ππVarπ   N  : Byte ;ππBEGINπ   ExitSave := ExitProc ;π   ExitProc := @RestoreInt09 ;π   GetIntVec( $09, OldInt09 ) ;π   SetIntVec( $09, @NewInt09 ) ;ππ   WriteLn( '   Display "make" and "break" scan codes ' ) ;π   WriteLn ;π   WriteLn( '   Hit the <Esc> key to exit ' ) ;π   Repeatπ      Delay( 400 ) ;               { make it easy to overrun keyboard }π      N := Ord( ReadKey ) ;        { n is the scan code from NewInt09 }π      If N < 128 thenπ         WriteLn( 'Make  ', n )π      Elseπ         WriteLn( '    Break  ', n - 128 ) ;π   Until n = 1 ;      { the make code for Esc }πEND.π                                          18     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Extended Keys            IMPORT              28          { MICHAEL NICOLAI }ππUsesπ  Dos;ππFunction Get_Extended_KeyCode : Word;πVarπ  regs : Registers;πbeginπ  regs.ah := $10;π  intr($16, regs);π  Get_Extended_KeyCode := (regs.ah shl 4) + regs.al;πend;ππ{πThis Function waits Until a key is pressed.  The upper Byte contains theπscan code, the lower Byte contains the ASCII code.  If you don't want yourπProgram to hang if no key is pressed, use this funtion to check if anyπkeycode is actually present in the keyboard buffer:π}ππFunction Check_For_Extended_KeyStroke : Boolean;  { like KeyPressed }πVarπ  regs : Registers;πbeginπ  regs.ah := $11;π  intr($16, regs);π  Check_For_Extended_Keystroke := False;π  if ((regs.flags and fzero) = 0) thenπ    Check_For_Extended_Keystroke := True;πend;ππ{πAfter this Function returns True, the keycode can be read Withπ'Get_Extended_KeyCode'.ππHere are the routines my Functions are based on:ππINTERRUPT 16h - Function 10hπKeyboard - Get enhanced keystrokeππPurpose: Wait For any keyboard input.πAvailable on: AT or PS/2 With enhanced keyboard support only.πRestrictions: none.πRegisters at call: AH = 10h.πReturn Registers: AH = scan code, AL = ASCII codeπDetails: if no keystroke is available, this Function waits Until one isπ         placed in the keyboard buffer. Unlike Function 00h, this Functionπ         does not discard extended keystrokes.πConflicts: none known.πππINTERRUPT 16h - Function 11hπKeyboard - Check For enhanced keystrokeππPurpose: Checks For availability of any keyboard input.πAvailable on: AT or PS/2 With enhanced keyboard only.πRestrictions: none.πRegisters at call: AH = 11hπReturn Registers: ZF set if no keystroke availableπ                  ZF clear if keystroke availableπ                     AH = scan codeπ                     AL = ASCII codeπDetails: if a keystroke is available, it is not removed from the keyboardπ         buffer. Unlike Function 01h, this Function does not discard extendedπ         keystrokes.πconflicts: none known.πππINTERRUPT 16h - Function 12hπKeyboard - Get extended shift statesππPurpose: Returns all shift-flags information from enhanced keyboards.πAvailable: AT or PS/2 With enhanced keyboard only.πRestrictions: none.πRegisters at call: AH = 12hπReturn Registers: AL = shift flags 1 (same as returned by Function 02h):π                       bit 7: Insert activeπ                           6: CapsLock activeπ                           5: NumLock activeπ                           4: ScrollLock activeπ                           3: Alt key pressed (either Alt on 101/102-keyπ                              keyboard)π                           2: Crtl key pressed (either Ctrl on 101/102-keyπ                              keyboard)π                           1: left shift key pressedπ                           0: right shift key pressedππ                  AH = shift flags 2:π                       bit 7: SysRq key pressedπ                           6: CapsLock pressedπ                           5: NumLock pressedπ                           4: ScrollLock pressedπ                           3: right Alt key prssedπ                           2: right Ctrl key pressedπ                           1: left Alt key pressedπ                           0: left Ctrl key pressedπDetails: AL bit 3 is set only For left Alt key on many machines. AH bits 7π         through 4 are always clear on a Compaq SLT/286.πConflicts: none known.π}π                                                                           19     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Trap CTRL-BREAK          IMPORT              13          {  >> What sort of code do I need to include in a pascal Program (Writen inπ  >> Borland Pascal 6.0) to disable CTRL-BREAK and CTRL-C?π}πUnit CAD;ππInterfaceππUses Dos;ππVarπ  Int9Handler  : Pointer;ππProcedure InterceptCtrlAltDel;πProcedure RestoreCAD;ππ  ImplementationππProcedure InterceptCtrlAltDel; Assembler;ππConstπ  Ctrl         = 4;π  Alt          = 8;π  Del          = $53;π  KbdPort      = $60;                  { Keyboard port }π  KbdCtrlPort  = $61;                  { Keyboard control port }π  PIC          = $20;                  { 8259 Interrupt controller }π  EOI          = $20;                  { end-of-interrupt }ππ  Asmππ  PUSH   AXπ  PUSH   DSπ  MOV    AX, SEG @Dataπ  MOV    DS, AXπ  STIπ  in     AL, KbdPortπ  and    AL, 01111111bπ  CMP    AL, Delπ  JNE    @2ππ  @1 :     MOV    AH, 2               { BIOS Get keyboard flags service }π  inT    16hπ  TEST   AL, Ctrl + Altπ  JNZ    @3ππ  @2 :     PUSHFπ  CALL   [Int9Handler]π  JMP    @4ππ  @3 :     in     AL, KbdCtrlPortπ  MOV    AH, ALπ  or     AL, 10000000bπ  OUT    KbdCtrlPort, ALπ  XCHG   AH, ALπ  OUT    KbdCtrlPort, ALπ  CLIππ  MOV    AL, EOIπ  OUT    PIC, ALπ  @4 :     POP    DSπ  POP    AXπ  IRET                       { make sure we return correctly }πend;  { InterceptCtrlAltDel }ππProcedure RestoreCAD;ππbeginπ  SETinTVEC (9, Int9Handler);πend;  { RestoreCAD }πππbeginπ  GETinTVEC (9, Int9Handler);π  SETinTVEC (9, @InterceptCtrlAltDel);πend. {Unit CAD}ππ                                                                                            20     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Trap CTRL-BREAK #2       IMPORT              19          {Here is my solution to the problem of trapping Ctrl-Alt-Del. As extra suger,πI'm providing hooks to make this Program TSR. Happy hacking!ππ<<File: trapboot.pas>>ππ{$m 1024,0,0} { Necesarry if you want to make the Program resident. }π{****************************************************************************}π{* NoBoot                                                                   *}π{*                                                                          *}π{* This Program stops rebooting While it is running by trapping             *}π{* Ctrl-Alt-Del.                                                            *}π{*                                                                          *}π{----------------------------------------------------------------------------}ππUsesπ  Dos, Crt;ππVarπ  OldKBVec : Pointer;ππ{ Declare all Variables in our interrupt routine global so that no stack }π{ allocation of Variables will be done during the interrupt.             }πVarπ  Regs : Registers;π  temp : Byte;π  KBflag1: Byte Absolute $40:$17;ππProcedure MyKB; inTERRUPT;πConstπ  EOI = $20;π  KB_DATA = $60;π  KB_CTL = $61;π  inT_CTL = $20;π  DEL_sc = $53;   { Scancode of the del key }ππbeginπ  { Check if Alt and Ctrl are pressed }π  if ((KBFlag1 and 4)=4) and ((KBFlag1 and 8)=8) andπ    (Port[KB_DATA]= DEL_sc) then begin { get scancode of pressed key }ππ    { The following four lines signals that the key is read and that the }π    { hardware interrupt is over. }π    temp:=Port[Kb_CTL];π    Port[KB_CTL]:= temp or $80;π    Port[KB_CTL]:= temp;π    Port[inT_CTL]:= EOI;ππ    { Don't do ANYTHinG here that requires BIOS. This 'Writeln' is using the }π    { Crt Unit.                                                              }π    Writeln('Ouch! That hurts!');  { Show we are here and alive! }π  endπ  else beginπ    intr($69, Regs); { Call the old interrupt routine }π  end;πend;ππVarπ  Ch : Char;ππbeginπ  GetIntVec($9, OldKBVec);π  SetIntVec($69, OldKBVec);π  SetIntVec($9, @MyKB);ππ  { Keep(0); } { Uncomment and erase the rest of the lines to make this Program}ππ  Repeatπ    Writeln('Press escape to Exit. or Ctrl-Alt-Del if you want...');π    ch:= ReadKey;π  Until ch=#27;ππ  { Forgetting the next line will very surely crash your Computer. }π  SetIntVec($9, OldKbVec);πend.π  21     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Trap PAUSE Key           IMPORT              10          {The problem is that the pause key actually paUses the Computerπvia hardware.  to reset the pause, you can use the timer interruptπto generate a reset process at every tick.  The method hereπwas taken from some Computer magazine.π}ππProgram TrapPause;πUses Dos;πVarπ  Timerint : Pointer;π  PauseFlag : Boolean;ππProcedure PauseDetect(flags,CS,IP,AX,BX,CX,DX,SI,DI,DS,ES,BP: Word);π  {This latches on to the system timer interrupt to detect if theπ   pause key has been pressed, and if so to reset the system to allowπ   operation to continue and to set Pauseflag = True}π  interrupt;π  beginπ    if memw[$0:$418] and 8 = 8 then  {Test bit 3}π    beginπ      Pauseflag := True;π      memw[$0:$418] := memw[$0:$418] and $F7; {Set bit 3 = 0}π    end;π    Inline($9C/              {PushF}π           $3E/              {DS}π           $FF/$1E/timerint);{Far call to usual timer interrupt}π  end;πππbeginπ  Getintvec($08,Timerint);      {Save old interrupt For timer}π  Setintvec($08,@PauseDetect);  {Redirect timer to PauseDetect}πend.ππ                                                                                                                        22     05-28-9313:49ALL                      SWAG SUPPORT TEAM        Trap PAUSE Key #2        IMPORT              28          {GE> Does anyone know how to disable the pause key?ππ Here's one way, done in Assembly, With example Turbo Pascal code ...π}π(*******************************************************************)π Program TestTrapPause;             { demo disabling the Pause key  }π Uses   Crt,                        { import CheakBreak, KeyPressed }π        Dos;                        { import GetIntVec, SetIntVec   }π Var    old09Vector : Pointer;      { to hold original ISR          }π        loopc,                      { a loop count                  }π        ppress      : Word;         { counts Pause key presses      }π{-------------------------------------------------------------------}π{ the following Procedures|Functions mask & count Pause keystrokes  }π Procedure InitTrapPause( oldVector : Pointer );    EXTERNAL;π Procedure TrapPause; Interrupt;                    EXTERNAL;π Function  PausePresses : Word;                     EXTERNAL;π Procedure ForgetPaUses;                            EXTERNAL;π {$L NOPAUSE.OBJ}                   { Assembly, Near calls          }π{-------------------------------------------------------------------}π beginπ    ClrScr;π    CheckBreak := False;            { don't allow Ctrl-Break        }ππ    GetIntVec( 9, old09Vector );    { get current keyboard ISR      }π    InitTrapPause( old09Vector );   { pass vector to TrapPause      }π    SetIntVec( 9, @TrapPause );     { enable TrapPause ISR          }π    ForgetPaUses;                   { zero the PausePresses counter }ππ    loopc := 0;                     { initialize                    }π    WriteLn; WriteLn( 'Press the PAUSE key... ');ππ    Repeatπ        WriteLn;π        ppress := PausePresses;     { initial Pause press count     }π        While (ppress = PausePresses) and (not KeyPressed)π        do beginπ            inC( loopc ); if (loopc = 65535) then loopc := 0;π            Write( loopc:5, ' you''ve pressed the Pause key ' );π            Write( ppress, ' times',#13 );π        end; {While}π    Until KeyPressed;ππ    SetIntVec( 9, old09Vector );    { restore Pause & release ISR   }ππ end {TestTrapPause}.π(*******************************************************************)ππ{ The following TP Program will create NOPAUSE.ARC, which containsπ NOPAUSE.OBJ ...ππ Program A; Var G:File; Const V:Array [ 1..279 ] of Byte =(π26,8,78,79,80,65,85,83,69,46,79,66,74,0,94,248,0,0,0,43,26,67,140,78,π194,29,1,0,0,12,128,26,0,88,224,230,13,156,48,117,230,148,113,17,100,π74,19,47,150,14,0,0,64,96,200,19,34,69,136,96,146,136,162,13,0,1,2,2,π28,131,4,32,200,196,0,12,140,60,145,114,164,8,21,40,65,170,76,41,50,165,π204,68,6,48,101,22,129,34,133,230,204,41,96,38,54,72,226,36,9,21,42,82,π130,64,201,57,115,34,128,4,72,149,50,45,226,99,34,9,68,4,38,138,10,16,π13,84,28,0,1,38,46,226,102,99,209,17,1,46,70,77,44,123,132,64,218,137,π46,142,25,112,10,64,88,214,33,6,243,200,73,115,6,13,29,16,49,114,228,π144,1,226,136,156,50,103,222,200,201,3,98,138,11,43,124,221,148,65,200,π134,14,167,125,80,200,129,225,81,132,206,1,44,157,92,252,115,1,247,223,π92,0,176,64,152,3,1,250,25,0,72,6,92,132,154,56,44,238,105,218,125,56,π201,0,64,12,1,216,0,90,120,67,248,205,133,119,133,223,94,120,51,249,29,π(96 min left), (H)elp, More? 156,88,20,228,188,197,64,39,134,6,58,43,69,2,38,210,1,26,0);π begin Assign(G,'NOPAUSE.ARC'); ReWrite(G,Sizeof(V));π BlockWrite(G,V,1); Close(G); end (*Gbug1.5*).π}π                                                                             23     05-29-9308:53ALL                      SWAG SUPPORT TEAM        Various READ Key/Chars   IMPORT              19          {πAuthor : GAYLE DAVISππI have seen a number of messages recently about keyboard access.  Here areπsome neat FAST routines to use instead of ReadKey (Crt Unit).  Be advisedπthat in these routines, I add 128 to the HI Byte in order to be able to useπall 256 Characters.  Just remember to add 128 to test For all Function keys.π}ππUsesπ  Dos;ππFunction GetKey (Var Key : Word) : Boolean; Assembler;π{ determine if key pressed and return it as a Word }π{ if Lo(key) = 0 and Hi(key) <> 0 then we have a FN key ! }πAsmπ  MOV     AH, 1π  INT     16Hπ  MOV     AL, 0π  JE      @@1π  xor     AH, AHπ  INT     16Hπ  LES     DI, Keyπ  MOV     Word PTR ES : [DI], AXπ  MOV     AL, 1π @@1 :πend;ππFunction GetChar (Var Key : Char) : Boolean;π{ determine if key pressed and return it as a Char}πVarπ  c : Word;πbeginπ  Key := #0;π  if GetKey (c) thenπ  beginπ    GetChar := True;π    if (LO (c) = 0) and (HI (c) <> 0) thenπ      Key := CHR ( HI (c) + 128 )  { add 128 For FN keys }π    elseπ      Key := CHR (LO (c) );π  endπ  elseπ    GetChar := False;πend;ππFunction KeyReady : Char;π{ looks For and PEEKS at Char but DOES not read it out of buffer }π{ returns the Char it finds or #0 if no Character waiting        }πVarπ  Regs : Registers;π  Key  : Byte;πbeginπ  Regs.AH := 1;                          { determine if a key has been }π  INTR ( $16, Regs );                    { converted to a key code     }π  if ( Regs.Flags and FZERO = 0 ) thenπ  begin                          { yes, Character now in keyboard buffer }π                                 { determine what it is }π    if ( Regs.AL = 0 ) thenπ      Key := Regs.AH + 128π    elseπ      Key := Regs.AL;π  endπ  elseπ    Key := 0;π  KeyReady := CHR (Key);πend;ππProcedure ClearKeyBuffer;πVarπ  Regs : Registers;πbeginπ  Regs.AH := 0;                { Clear ENTIRE keyboard }π  INTR ( $16, Regs );          { buffer via the BIOS   }πend;ππFunction AnyKeyPressed (Ch : Char; Clear : Boolean) : Boolean;π{ Check if a Character is present in buffer, and optionally clears it }πVarπ  Key  : Char;π  Regs : Registers;ππbeginπ  Key := KeyReady;π  AnyKeyPressed := (Key = Ch);π  if (Key = Ch) and Clear thenπ    ClearKeyBuffer;πend;π                                                                                                                               24     05-31-9307:14ALL                      SWAG SUPPORT TEAM        Simple KEYSTATE Routines IMPORT              17          BB>procedure ShiftStatus(var Ins,π  >                          CapsLock,π  >                          NumLock,π  >                          ScrollLock,π  >                          Alt,π  >                          Ctrl,π  >                          LeftShift,π  >                          RightShift: Boolean);ππI thought this was a little tedious because it is a pain to have allπthose variables....so I made something like this:πππUnit KeyStats;ππInterfaceππ  Function RightShift: Boolean;π  Function LeftShift: Boolean;π  Function Control: Boolean;π  Function Alt: Boolean;π  Function ScrollLock: Boolean;π  Function NumLock: Boolean;π  Function CapsLock: Boolean;π  Function Insert: Boolean;ππImplementationππUses Dos;ππFunction ShiftState: Byte;πVar Regs: Registers;πBeginπ  Regs.Ah:=2;π  Intr($16, Regs);π  ShiftState:=Regs.Al;πEnd;ππFunction RightShift: Boolean;πBeginπ  RightShift:=(ShiftState and 1)<>0;πEnd;ππFunction LeftShift: Boolean;πBeginπ  LeftShift:=(ShiftState and 2)<>0;πEnd;ππFunction Control: Boolean;πBeginπ  Control:=(ShiftState and 4)<>0;πEnd;ππFunction Alt: Boolean;πBeginπ  Alt:=(ShiftState and 8)<>0;πEnd;ππFunction ScrollLock: Boolean;πBeginπ  ScrollLock:=(ShiftState and 16)<>0;πEnd;ππFunction NumLock: Boolean;πBeginπ  NumLock:=(ShiftState and 32)<>0;πEnd;ππFunction CapsLock: Boolean;πBeginπ  CapsLock:=(ShiftState and 64)<>0;πEnd;ππFunction Insert: Boolean;πBeginπ  Insert:=(ShiftState and 128)<>0;πEnd;ππEnd.ππHere is a little something that will turn on the light for you.πThe state of the keys below is at addrees $40 and offset $17 in memory, byπchanging the values at that location, you can turn on the CAPS, the NUM etc..πππTypeππ   Toggles      = (RShift, LShift, Ctrl, Alt,π                   ScrollLock, NumLock, CapsLock, Insert);π   Status       = Set of Toggles;ππVarπ   KeyStatus   : Status Absolute $40:$17;πππExample : to turn on the caps lock, do this :ππ                        KeyStatus := KeyStatus + [CapsLock];ππ                                                                                  25     05-31-9308:07ALL                      SWAG SUPPORT TEAM        Ctrl/Alt/Del Trapping    IMPORT              21          ==============================================================================π BBS: ─≡─ The Graphics Connection ─≡─ Specialiπ  To: JOE JACOBSON                 Date: 12-20-92 (15:25)πFrom: GUY MCLOUGHLIN             Number: 1137   [121] Pascal-ILπSubj: CTRL-ALT-DELETE TRAPPING   Status: Publicπ------------------------------------------------------------------------------π  ...Unit captured from FIDONET:ππUNIT CAD;ππ{- Area: PASCAL ---------------------}π{  Date: 10-16-92  22:12             }π{  From: Wilbert van Leijen          }π{    To: John Martzall               }π{  Subj: Ctrl-Alt-Delete             }π{------------------------------------}ππINTERFACEππUSES Dos;ππVARπ  Int9Handler  : POINTER;ππPROCEDURE InterceptCtrlAltDel;πPROCEDURE RestoreCAD;ππ  IMPLEMENTATIONππPROCEDURE InterceptCtrlAltDel; Assembler;ππCONSTπ  Ctrl         = 4;π  Alt          = 8;π  Del          = $53;π  KbdPort      = $60;                  { Keyboard port }π  KbdCtrlPort  = $61;                  { Keyboard control port }π  PIC          = $20;                  { 8259 Interrupt controller }π  EOI          = $20;                  { End-of-interrupt }ππ  ASMπ  { Make sure we can access our global data }ππ  PUSH   AXπ  PUSH   DSπ  MOV    AX, SEG @Dataπ  MOV    DS, AXπ  STIππ  { Read keyboard port and mask out the 'break bit'.π          Check whether the <Del> key was pressed. }ππ  IN     AL, KbdPortπ  AND    AL, 01111111bπ  CMP    AL, Delπ  JNE    @2ππ  { <Del> key was pressed, now check whether <Ctrl> and <Alt>π          are held down }ππ  @1 :     MOV    AH, 2               { BIOS Get keyboard flags service }π  INT    16hπ  TEST   AL, Ctrl + Altπ  JNZ    @3ππ  { Chain to previous owner of INT 9 }ππ  @2 :     PUSHFπ  CALL   [Int9Handler]π  JMP    @4ππ  { Ctrl-Alt-Del combination found: send the break code }ππ  @3 :     IN     AL, KbdCtrlPortπ  MOV    AH, ALπ  OR     AL, 10000000bπ  OUT    KbdCtrlPort, ALπ  XCHG   AH, ALπ  OUT    KbdCtrlPort, ALπ  CLIππ  { Signal 'End Of Interrupt' to the 8259 interrupt controller chip }ππ  MOV    AL, EOIπ  OUT    PIC, ALπ  @4 :     POP    DSπ  POP    AXπ  IRET                       { make sure we return correctly }πEND;  { InterceptCtrlAltDel }ππPROCEDURE RestoreCAD;ππBEGINπ  SETINTVEC (9, Int9Handler);πEND;  { RestoreCAD }ππBEGINπ  GETINTVEC (9, Int9Handler);π  SETINTVEC (9, @InterceptCtrlAltDel);πEND.π                               - Guyπ---π ■ DeLuxe²/386 1.25 #5060 ■π ■ QNet3ß ■ ILink - Canada Remote Systems - Toronto, Ont (416) 798-4713π                                                                    26     06-22-9309:10ALL                      SWAG SUPPORT TEAM        Another Ctrl-Break Trap  IMPORT              11          UNIT Break;π{This unit traps the Ctrl-Break sequence}ππINTERFACEπUSESπ  DOS;πCONSTπ  BrkTrapped : Boolean = FALSE;πPROCEDURE TrapCtrlBrkOn;πPROCEDURE TrapCtrlBrkOff;ππIMPLEMENTATIONπCONSTπ  CtrlBrkInterrupt     = $1B;π  BrkTrapSet : Boolean = FALSE;πVARπ  OldBrkVector : Pointer;π{ The following procedure is the new Ctrl-Breakπ  Interrupt handler. It traps the Ctrl-Break keyπ  sequence and setsa flag for the currentlyπ  running program to check.  You should do anyπ  special processing based on this flag's value}π{$F+}πPROCEDURE NewCtrlBrkVector; INTERRUPT;π{$F-}πBEGINπ  INLINE($FA); {Clear interrupts instruction -CLI}π  {Reset bit 7 low}π  Mem[$0040:$0071] := Mem[$0040:$0071] AND $E;π  BrkTrapped := TRUE;π  INLINE($FB) {Set interrupts instruction - STI}πEND;ππPROCEDURE TrapCtrlBrkOn;πBEGINπ  {Make sure no stacked calls are possible}π  IF NOT BrkTrapSet THENπ   BEGINπ    BrkTrapSet := TRUE;π    GetIntVec(CtrlBrkInterrupt, OldBrkVector);π    SetIntVec(CtrlBrkInterrupt, @NewCtrlBrkVector)π   ENDπEND;ππPROCEDURE TrapCtrlBrkOff;πBEGIN {Check if there is an old vector to restore}π  IF BrkTrapSet THENπ    BEGINπ      BrkTrapSet := FALSE;π      SetIntVec(CtrlBrkInterrupt, OldBrkVector)π    ENDπEND;ππEND.π                                                                 27     06-22-9309:17ALL                      SWAG SUPPORT TEAM        OOP Keyboard Routines    IMPORT              25          UNIT Keybd;  { Keybd.PAS / Keybd.TPU }ππINTERFACEππUSES Crt, Dos;ππTYPEπ  CType = ( UBAR, BLOCK );π  Keyboard = OBJECTπ    ThisCursor: CType;π    PROCEDURE InitKeyBd;π    PROCEDURE SetCursor( Cursor: CType );π    FUNCTION  GetCursor: CType;π    FUNCTION  GetKbdFlags: Byte;π    FUNCTION  GetKey( VAR KeyFlags: Byte; VAR FunctKey: Boolean;π                                        VAR Ch: Char ): Boolean;π  END;ππ{***************************************************************}π                      IMPLEMENTATIONπ{***************************************************************}πππ{Keyboard}ππ{-------------------------------------------------π- Name   : InitKeyBd                             -π- Purpose: Set the cursor to underline style     -π-          and empty keyboard buffer             -π-------------------------------------------------}ππPROCEDURE Keyboard.InitKeyBd;π  VARπ    Ch : Char;π  BEGINπ    SetCursor( UBAR );π    WHILE( KeyPressed ) DO Ch := ReadKey;π  END;ππ{-------------------------------------------------π- Name   : SetCursor                             -π- Purpose: Modify number of lines for cursor     -π-------------------------------------------------}ππPROCEDURE Keyboard.SetCursor;π  VARπ    Regs: Registers;π  BEGINπ    CASE Cursor OFπ      UBAR:  Regs.Ch := 6;π      BLOCK: Regs.Ch := 1;π    END;π    Regs.CL := 7;π    Regs.AH := 1;π    Intr( $10, Regs );π  END;ππ{-------------------------------------------------π- Name   : GetKbdFlags                           -π- Purpose: Monitor the Insert key                -π- Output : Shift key status flag byte            -π-------------------------------------------------}ππFUNCTION  Keyboard.GetKbdFlags: Byte;π  VARπ    Regs: Registers;π  BEGINπ    (* FOR enhanced keyboards: AH := $12 *)π    (* FOR normal keyboards:   AH := $02 *)π    Regs.AH := $12;π    Intr( $16, Regs );π    IF( Regs.AX AND $80 = $80 ) THEN SetCursor( BLOCK )π                                ELSE SetCursor( UBAR );π    GetKbdFlags := Regs.AX;π  END;ππ{-------------------------------------------------π- Name   : GetCursor                             -π- Purpose: Query current cursor state            -π-------------------------------------------------}ππFUNCTION  Keyboard.GetCursor;π  BEGINπ    GetCursor := ThisCursor;π  END;ππ{-------------------------------------------------π- Name   : GetKey                                -π- Purpose: Get a keypress contents if any        -π-          Updates a function keypressed flag    -π-------------------------------------------------}ππFUNCTION  Keyboard.GetKey;π  VARπ    Result : Boolean;π  BEGINπ    Result := KeyPressed;π    FunctKey := FALSE;π    Ch := #$00;       {Use this to check for Function key press}π    IF Result THEN BEGINπ      Ch := ReadKey;π      IF( KeyPressed AND ( Ch = #$00 ) ) THEN BEGINπ        Ch := ReadKey;π        FunctKey := TRUE;π        END;π      END;π    KeyFlags := GetKbdFlags;π    GetKey := Result;π    END;ππEND.π                                                                                                                28     06-22-9309:21ALL                      SWAG SUPPORT TEAM        Disable PRINT SCREEN     IMPORT              14          ===========================================================================π BBS: Canada Remote SystemsπDate: 06-15-93 (09:40)             Number: 26422πFrom: CHRIS JANTZEN                Refer#: NONEπ  To: JANOS SZAMOSFALVI             Recvd: NO  πSubj: Re: No print screen            Conf: (1221) F-PASCALπ---------------------------------------------------------------------------πOn Sunday June 13 1993, Janos Szamosfalvi wrote to All:ππ JS> PROGRAM NoPrintScreen;ππ JS> PROCEDURE Null; Interrupt;π JS> BEGINπ JS> END;ππ JS> BEGINπ JS>   SetIntvec($05, @Null);π JS>   Keep(1);π JS> END.ππ JS> I have several questions about this code:π JS>   a) when it comes to reloading COMMAND.COM, my computer hangsπ JS>      with memory allocation error when the above program is inπ JS>      memory.π JS>      Any idea why?ππAn easy one: You forgot to tell the compiler how much memory your programπwants. Put the following directive at the beginning of your program:ππ{$M 1024,0,0}πPROGRAM NoPrintScreen;π[...]ππThat little "{$M" tells the compiler to tell DOS that you don't want a lot ofπRAM when loaded. Otherwise, your application will allocate (and Keep) allπavailable RAM in the system (effectively making your program a 640K TSR!).ππ JS>   b) can anyone tell me how to modify this so PrintScrenπ JS>      would be the second Esc key?ππAh, that would be a bit trickier.... You'd need to trap Int 9 using someπassembly code (but my brain is mush right now, so I'll let someone else helpπyou on that).ππChris KB7RNL =->ππ--- GoldED 2.41π * Origin: SlugPoint * Home to fine silly people everywhere (1:356/18.2)π                                                        29     07-16-9306:10ALL                      YVAN RIVARD              Another READKEY in ASM   IMPORT              16        ===========================================================================π BBS: The Beta ConnectionπDate: 06-20-93 (12:25)             Number: 1081πFrom: YVAN RIVARD                  Refer#: 984π  To: BOB GIBSON                    Recvd: NO  πSubj: console I/O                    Conf: (232) T_Pascal_Rπ---------------------------------------------------------------------------πBG> You know, since I wrote my own unit to replace CRT, you'd think I'd knowπBG> something like that!πBG> Which brings up a question...my unit uses direct video writes, andπBG> (supposedly) so does TP unless you tell it otherwise.  So why does myπBG> unit do a screen faster than TP's units?  Not as much overhead?ππYou made your own 'Crt'? I'd like some help!πThe only thing I haven't been able to do so far is the stupid KeyPressed...πI have successfully made a really good ReadKey (return a String [2], so I canπeven read arrows, Functions keys (even F11 and F12))ππHere's my ReadKey (I case anybody would like to have it),πbut I you could help me with the KeyPressed...π(Byt the way, does your 'direct video' is made like this?π Typeπ    VideoChar = Recordπ                   Ascii : Char;π                   Color : Byte;π                end;π    Varπ       VideoRam : Array [1..25,1..80] of VideoChar Absolute $B800:0000; )ππHere's my 'ReadKey':ππFunction Inkey : String;π   Varπ      K : Word;π      T : String [2];π   Beginπ      Asmπ         mov  ah, 10hπ         int  16hπ         mov  K, axπ      end;π      T := '';π      If ((K and 255) = 0) or ((K and 255) = 224) thenπ         T := ' '+ Chr (Trunc ((K and 65280) / 256))π      elseπ         T := Chr (K and 255);π      Inkey := T;π   End;ππSo what about a 'KeyPressed' ?ππThanks 'n byeπ---π * Info Tech BBS 819-375-3532π * PostLink(tm) v1.06  ITECH (#535) : RelayNet(tm)π                                                                                                       30     07-16-9306:14ALL                      LAVI TIDHAR              Keyboard Buffer Routines IMPORT              26        Unit TPbuffer;ππ(* TP-Buffer unit version 1.1 /Update              *)π(* Using the keyboard's buffer in Turbo Pascal     *)π(* This unit is released to the public domain      *)π(* by Lavi Tidhar on 5-10-1992                     *)ππ(* This unit adds three special functions not      *)π(* incuded in the Turbo Pascal regular package     *)ππ(* You may alter this source code, move the        *)π(* procedures to your own programs. Please do      *)π(* NOT change these lines of documentation         *)ππ(* This source might teach you about how to        *)π(* use interrupts in pascal, and the keyboard's    *)π(* buffer. from the other hand, it might not :-)   *)ππ(* Used: INT 16, functions 0 and 1                 *)π(*       INT 21, function 0Ch                      *)ππ(* INT 16 - KEYBOARD - READ CHAR FROM BUFFER, WAIT IF EMPTYπ           AH = 00hπ           Return: AH = scan codeπ                   AL = character         *)ππ(* INT 16 - KEYBOARD - CHECK BUFFER, DO NOT CLEARπ           AH = 01hπ           Return: ZF = 0 character in bufferπ                       AH = scan codeπ                       AL = characterπ                       ZF = 1 no character in buffer *)ππ(* INT 21 - DOS - CLEAR KEYBOARD BUFFERπ        AH = 0Chπ        AL must be 1, 6, 7, 8, or 0Ah.π        Notes: Flushes all typeahead input, then executes function specified by ALπ        (effectively moving it to AH and repeating the INT 21 call).π        If AL contains a value not in the list above, the keyboard buffer isπ        flushed and no other action is taken. *)ππ(* For more details/help etc, you can contact me on: *)ππ(* Mail: Lavi Tidharπ         46 Bantam Dr.π         Blairgowrieπ         2194π         South Africa π*)ππ(* Phone:π          International: +27-11-787-8093π          South Africa:  (011)-787-8093π*)ππ(* Netmail: The Catacomb BBS 5:7101/45 (fidonet)π            The Catacomb BBS 80:80/100 (pipemail)π*)ππInterfaceππUses Dos;ππFunction GetScanCode:Byte; (* Get SCAN CODE from buffer, wait if empty *)πFunction GetKey:Char;      (* Get Char from buffer, do NOT wait *)πProcedure FlushKB;ππImplementationππFunction GetKey:Char;π Var Regs:Registers;π Beginπ  Regs.AH:=1;                (* Int 16 function 1 *)π  Intr ($16,Regs);           (* Read a charecter from the keyboard buffer *)π  GetKey:=Chr (Regs.AL);     (* do not wait. If no char was found, CHR(0) *)π End;                        (* (nul) is returned *)ππFunction GetScanCode:Byte;   (* Int 16 function 0 *)π Var Regs:Registers;         (* The same as CRT's Readkey, but gives you *)π  Begin                      (* the scan code. Esp usefull when you want to *)π   Regs.AH:=0;               (* use special keys as the arrows, there will *)π   Intr ($16,Regs);          (* be a conflict when using ReadKey *)π   GetScanCode:=Regs.AH;π  End;ππProcedure FlushKB;           (* INT 21 function 0C *)π Var Regs:Registers;         (* Flushes (erase) the keyboard buffer *)π  Begin                      (* ONLY. No other function is executed *)π   Regs.AH:=$0C;π   Regs.AL:=2;π   Intr ($21,Regs);π  End;ππEnd.π                                                                                                                        31     08-17-9308:41ALL                      SWAG SUPPORT TEAM        Using 101 Keys - F11/F12 IMPORT              8         {  Return Extended keys for 101 Keyboard including F11/F12.π   If key is extended, the BOOLEAN = TRUE.  This is needed as Home key willπ   return the same character value as 'G' }ππUSES DOS;ππVAR Ch : Char;π    Ext : BOOLEAN;ππfunction ExReadKey(VAR Extended : BOOLEAN) : char;πvar Regs : registers;πbeginπ  Regs.AX := $1000;π  Intr($16,Regs);π  Extended := (Regs.AL = 0) OR (Regs.AL > 127);π  IF Extended THEN ExReadKey  := Chr(Regs.AH)π  ELSE ExReadKey := Chr(Regs.AL);πend;ππfunction ReadKey : char;π{ This function adds 128 to char if it is extended }πvar Regs : registers;πbeginπ  Regs.AX := $1000;π  Intr($16,Regs);π  IF (Regs.AL = 0) OR (Regs.AL > 127) THENπ  ReadKey  := Chr(Regs.AH + 128) ELSE ReadKey := Chr(Regs.AL);πend;ππBeginπRepeatπch := ReadKey;πWriteLn(ch,' ',Ext,' ',ORD(Ch));πUntil Ch = #27;πEND.                                                                                 32     08-17-9308:45ALL                      SWAG SUPPORT TEAM        Set KBD delay/repeat rateIMPORT              16        {***********************************************π* KBSETUP - set the desired delay/repeat rate  *π* for the keyboard.                            *π***********************************************}ππUSESπ    Dos;ππPROCEDURE Usage;π  BEGINπ    WriteLn;π    WriteLn('KBSETUP Command format:');π    WriteLn;π    WriteLn('KBSETUP  n {A | B | C | D} ');π    WriteLn;π    Write  ('n            A number from 0 to 31');π    WriteLn(' to set the keyboard repeat rate.');π    Write  ('             0 is the fastest and');π    WriteLn(' 31 is the slowest.');π    WriteLn;π    Write  ('A,B,C or D   Sets the keyboard');π    WriteLn(' delay before repeating');π    Write  ('             to 1/4, 1/2, 3/4 and');π    WriteLn(' 1 second.');π    Halt(1);π  END;ππVARπ  KBDelay, KBRepeat, I : byte;π  Code                 : integer;π  Regs                 : Registers;π  KeyString            : string[1];ππBEGINππ  KBDelay := 0;π  KBRepeat := 0;ππ  IF ParamCount = 0 THENπ    Usageπ  ELSEπ    BEGINπ      FOR I := 1 TO ParamCount DOπ        BEGINπ          KeyString := ParamStr(I);π        IF UpCase(KeyString[1]) in ['A'..'D'] THENπ          KBDelay := Ord(UpCase(KeyString[1]))π                       - Ord('A')π        ELSEπ          BEGINπ             {$R-}π            Val(ParamStr(I),KBRepeat,Code);π             {$R+}π            IF (Code <> 0) or (KBRepeat < 0) orπ               (KBRepeat > 31) THENπ              BEGINπ                Write('-- Invalid Letter or');π                Write(' Number Entered --> ');π                WriteLn(ParamStr(I));π                Usageπ              ENDπ          ENDπ        END;ππ    { Set the keyboard delay/repeat rate }ππ      WITH Regs DOπ        BEGINπ          AX := $0305;π          BH := KBDelay;π          BL := KBRepeat;π          Intr($16,Regs)π        ENDπ    END {of the IF/THEN/ELSE instruction}πEND.π                                                                             33     08-18-9312:26ALL                      JOSE ALMEIDA             Complete Scan Codes      IMPORT              210       πUNIT HTkb;ππ{ Complete set of all keyboard scan codes.π  Part of the Heartware Toolkit v2.00 (HTkb.PAS) for Turbo Pascal.π  Author: Jose Almeida. P.O.Box 4185. 1504 Lisboa Codex. Portugal.π          I can also be reached at RIME network, site ->TIB or #5314.π  Feel completely free to use this source code in any way you want, and, ifπ  you do, please don't forget to mention my name, and, give me and Swag theπ  proper credits. }ππINTERFACEππconstππ{ letters ······························································ }ππ  kb_AA                  = $1E61;     { a                                }π  kb_A                   = $1E41;     { A                                }π  kb_CtrlA               = $1E01;     { ^A                               }π                                      { SOH - Start Of Header            }π  kb_AltA                = $1E00;     { ALT A                            }ππ  kb_BB                  = $3062;     { b                                }π  kb_B                   = $3042;     { B                                }π  kb_CtrlB               = $3002;     { ^B                               }π                                      { STX - Start Of Text              }π  kb_AltB                = $3000;     { ALT B                            }ππ  kb_CC                  = $2E63;     { c                                }π  kb_C                   = $2E43;     { C                                }π  kb_CtrlC               = $2E03;     { ^C                               }π                                      { ETX - End Of Text                }π  kb_AltC                = $2E00;     { ALT C                            }ππ  kb_DD                  = $2064;     { d                                }π  kb_D                   = $2044;     { D                                }π  kb_CtrlD               = $2004;     { ^D                               }π                                      { EOT - End Of Transmission        }π  kb_AltD                = $2000;     { ALT D                            }ππ  kb_EE                  = $1265;     { e                                }π  kb_E                   = $1245;     { E                                }π  kb_CtrlE               = $1205;     { ^E                               }π                                      { ENQ - Enquire                    }π  kb_AltE                = $1200;     { ALT E                            }ππ  kb_FF                  = $2166;     { f                                }π  kb_F                   = $2146;     { F                                }π  kb_CtrlF               = $2106;     { ^F                               }π                                      { ACK - Acknowledge                }π  kb_AltF                = $2100;     { ALT F                            }ππ  kb_GG                  = $2267;     { g                                }π  kb_G                   = $2247;     { G                                }π  kb_CtrlG               = $2207;     { ^G                               }π                                      { BEL - Bell                       }π  kb_AltG                = $2200;     { ALT G                            }ππ  kb_HH                  = $2368;     { h                                }π  kb_H                   = $2348;     { H                                }π  kb_CtrlH               = $2308;     { ^H                               }π                                      { BS - BackSpace                   }π  kb_AltH                = $2300;     { ALT H                            }ππ  kb_II                  = $1769;     { i                                }π  kb_I                   = $1749;     { I                                }π  kb_CtrlI               = $1709;     { ^I                               }π                                      { HT - Horizontal Tab              }π  kb_AltI                = $1700;     { ALT I                            }ππ  kb_JJ                  = $246A;     { j                                }π  kb_J                   = $244A;     { J                                }π  kb_CtrlJ               = $240A;     { ^J                               }π                                      { LF - Line Feed                   }π  kb_AltJ                = $2400;     { ALT J                            }ππ  kb_KK                  = $256B;     { k                                }π  kb_K                   = $254B;     { K                                }π  kb_CtrlK               = $250B;     { ^K                               }π                                      { VT - Vertical Tab                }π  kb_AltK                = $2500;     { ALT K                            }ππ  kb_LL                  = $266C;     { l                                }π  kb_L                   = $264C;     { L                                }π  kb_CtrlL               = $260C;     { ^L                               }π                                      { FF - Form Feed (new page)        }π  kb_AltL                = $2600;     { ALT L                            }ππ  kb_MM                  = $326D;     { m                                }π  kb_M                   = $324D;     { M                                }π  kb_CtrlM               = $320D;     { ^M                               }π                                      { CR - Carriage Return             }π  kb_AltM                = $3200;     { ALT M                            }ππ  kb_NN                  = $316E;     { n                                }π  kb_N                   = $314E;     { N                                }π  kb_CtrlN               = $310E;     { ^N                               }π                                      { SO - Shift Out (numbers)         }π  kb_AltN                = $3100;     { ALT N                            }ππ  kb_OO                  = $186F;     { o                                }π  kb_O                   = $184F;     { O                                }π  kb_CtrlO               = $180F;     { ^O                               }π                                      { SI - Shift In (letters)          }π  kb_AltO                = $1800;     { ALT O                            }ππ  kb_PP                  = $1970;     { p                                }π  kb_P                   = $1950;     { P                                }π  kb_CtrlP               = $1910;     { ^P                               }π                                      { DEL - Delete                     }π  kb_AltP                = $1900;     { ALT P                            }ππ  kb_QQ                  = $1071;     { q                                }π  kb_Q                   = $1051;     { Q                                }π  kb_CtrlQ               = $1011;     { ^Q                               }π                                      { DC1 - Device Control 1           }π  kb_AltQ                = $1000;     { ALT Q                            }ππ  kb_RR                  = $1372;     { r                                }π  kb_R                   = $1352;     { R                                }π  kb_CtrlR               = $1312;     { ^R                               }π                                      { DC2 - Device Control 2           }π  kb_AltR                = $1300;     { ALT R                            }ππ  kb_SS                  = $1F73;     { s                                }π  kb_S                   = $1F53;     { S                                }π  kb_CtrlS               = $1F13;     { ^S                               }π                                      { DC3 - Device Control 3           }π  kb_AltS                = $1F00;     { ALT S                            }ππ  kb_TT                  = $1474;     { t                                }π  kb_T                   = $1454;     { T                                }π  kb_CtrlT               = $1414;     { ^T                               }π                                      { DC4 - Device Control 4           }π  kb_AltT                = $1400;     { ALT T                            }ππ  kb_UU                  = $1675;     { u                                }π  kb_U                   = $1655;     { U                                }π  kb_CtrlU               = $1615;     { ^U                               }π                                      { NAK - Negative Acknowlegde       }π  kb_AltU                = $1600;     { ALT U                            }ππ  kb_VV                  = $2F76;     { v                                }π  kb_V                   = $2F56;     { V                                }π  kb_CtrlV               = $2F16;     { ^V                               }π                                      { SYN - Syncronize                 }π  kb_AltV                = $2F00;     { ALT V                            }ππ  kb_WW                  = $1177;     { w                                }π  kb_W                   = $1157;     { W                                }π  kb_CtrlW               = $1117;     { ^W                               }π                                      { ETB - End of Text Block          }π  kb_AltW                = $1100;     { ALT W                            }ππ  kb_XX                  = $2D78;     { x                                }π  kb_X                   = $2D58;     { X                                }π  kb_CtrlX               = $2D18;     { ^X -                             }π                                      { CAN - Cancel                     }π  kb_AltX                = $2D00;     { ALT X                            }ππ  kb_YY                  = $1579;     { y                                }π  kb_Y                   = $1559;     { Y                                }π  kb_CtrlY               = $1519;     { ^Y                               }π                                      { EM - End of Medium               }π  kb_AltY                = $1500;     { ALT Y                            }ππ  kb_ZZ                  = $2C7A;     { z                                }π  kb_Z                   = $2C5A;     { Z                                }π  kb_CtrlZ               = $2C1A;     { ^Z                               }π                                      { SUB - Substitute                 }π  kb_AltZ                = $2C00;     { ALT Z                            }ππ{ numbers ······························································ }ππ  kb_1                   = $0231;     { 1                                }π  kb_Pad1                = $4F31;     { SHIFT 1      number pad          }π  kb_Alt1                = $7800;     { ALT 1                            }ππ  kb_2                   = $0332;     { 2                                }π  kb_Pad2                = $5032;     { SHIFT 2      number pad          }π  kb_Alt2                = $7900;     { ALT 2                            }π  kb_Ctrl2               = $0300;     { ^1 (NUL)                         }ππ  kb_3                   = $0433;     { 3                                }π  kb_Pad3                = $5133;     { SHIFT 3      number pad          }π  kb_Alt3                = $7A00;     { ALT 3                            }ππ  kb_4                   = $0534;     { 4                                }π  kb_Pad4                = $4B34;     { SHIFT 4      number pad          }π  kb_Alt4                = $7B00;     { ALT 4                            }ππ  kb_5                   = $0635;     { 5                                }π  kb_Pad5                = $4C35;     { SHIFT 5      number pad          }π  kb_Alt5                = $7C00;     { ALT 5                            }ππ  kb_6                   = $0736;     { 6                                }π  kb_Pad6                = $4D36;     { SHIFT 6      number pad          }π  kb_Ctrl6               = $071E;     { ^6 (RS)                          }π  kb_Alt6                = $7D00;     { ALT 6                            }ππ  kb_7                   = $0837;     { 7                                }π  kb_Pad7                = $4737;     { SHIFT 7      number pad          }π  kb_Alt7                = $7E00;     { ALT 7                            }ππ  kb_8                   = $0938;     { 8                                }π  kb_Pad8                = $4838;     { SHIFT 8      number pad          }π  kb_Alt8                = $7F00;     { ALT 8                            }ππ  kb_9                   = $0A39;     { 9                                }π  kb_Pad9                = $4939;     { SHIFT 9      number pad          }π  kb_Alt9                = $8000;     { ALT 9                            }ππ  kb_0                   = $0B30;     { 0                                }π  kb_Pad0                = $5230;     { SHIFT 0      number pad          }π  kb_Alt0                = $8100;     { ALT 0                            }ππ{ etc: characters ······················································ }ππ  kb_Less                = $333C;     { <                                }π  kb_Great               = $343E;     { >                                }ππ  kb_Minus               = $352D;     { -                                }π  kb_GrayMinus           = $4A2D;     { -                                }π  kb_CtrlMinus           = $0C1F;     { ^-                               }π  kb_AltMinus            = $8200;     { ALT -                            }π  kb_ShiftGrayMinus      = $4A2D;     { SHIFT -                          }ππ  kb_Plus                = $1A2B;     { +                                }π  kb_GrayPlus            = $4E2B;     { +                                }π  kb_WhitePlus           = $0D2B;     { +                                }π  kb_ShiftGrayPlus       = $4E2B;     { SHIFT +                          }ππ  kb_Equal               = $0D3D;     { =                                }π  kb_AltEqual            = $8300;     { ALT =                            }ππ  kb_Slash               = $352F;     { /                                }ππ  kb_BackSlash           = $2B5C;     { \                                }π  kb_CtrlBackSlash       = $2B1C;     { ^\                               }π                                      { FS - File Separator              }ππ  kb_OpenBracket         = $1A5B;     { [                                }π  kb_CtrlOpenBracket     = $1A1B;     { ^[                               }π                                      { ESC - Escape                     }ππ  kb_CloseBracket        = $1B5D;     { ]                                }π  kb_CtrlCloseBracket    = $1B1D;     { ^]                               }π                                      { GS - Group Separator             }ππ  kb_OpenParenthesis     = $0A28;     { (                                }ππ  kb_CloseParenthesis    = $0B29;     { )                                }ππ  kb_OpenBrace           = $1A7B;     { can't write it                   }ππ  kb_CloseBrace          = $1B7D;     { can't write it                   }ππ  kb_Apostrophe          = $2827;     { '                                }π  kb_Grave               = $2960;     { `                                }ππ  kb_Quote               = $2822;     { "                                }ππ  kb_Tilde               = $297E;     { ~                                }ππ  kb_Cater               = $075E;     { ^                                }ππ  kb_Semicolon           = $273B;     { ;                                }ππ  kb_Comma               = $332C;     { ,                                }ππ  kb_Colon               = $273A;     { :                                }ππ  kb_Period              = $342E;     { .                                }π  kb_ShiftPeriod         = $532E;     { SHIFT .      number pad          }ππ  kb_GrayAsterisk        = $372A;     { *                                }π  kb_WhiteAsterisk       = $1A2A;     { *                                }ππ  kb_ExclamationPoint    = $0221;     { !                                }ππ  kb_QuestionMark        = $353F;     { ?                                }ππ  kb_NumberSign          = $0423;     { #                                }ππ  kb_Dollar              = $0524;     { $                                }ππ  kb_Percent             = $0625;     { %                                }ππ  kb_AmpersAnd           = $0826;     { &                                }ππ  kb_At                  = $0340;     { @                                }π                                      { ^@  = 00h                        }π                                      { NUL - Null Character             }π  kb_UnitSeparator       = $0C5F;     { _                                }π                                      { ^_  = 1Fh                        }π                                      { US  - Unit Separator             }ππ  kb_Vertical            = $2B7C;     { |                                }ππ  kb_Space               = $3920;     { SPACE BAR                        }ππ{ functions ···························································· }ππ  kb_F1                  = $3B00;     { F1                               }π  kb_ShiftF1             = $5400;     { SHIFT F1                         }π  kb_CtrlF1              = $5E00;     { ^F1                              }π  kb_AltF1               = $6800;     { ALT F1                           }ππ  kb_F2                  = $3C00;     { F2                               }π  kb_ShiftF2             = $5500;     { SHIFT F2                         }π  kb_CtrlF2              = $5F00;     { ^F2                              }π  kb_AltF2               = $6900;     { ALT F2                           }ππ  kb_F3                  = $3D00;     { F3                               }π  kb_ShiftF3             = $5600;     { SHIFT F3                         }π  kb_CtrlF3              = $6000;     { ^F3                              }π  kb_AltF3               = $6A00;     { ALT F3                           }ππ  kb_F4                  = $3E00;     { F4                               }π  kb_ShiftF4             = $5700;     { SHIFT F4                         }π  kb_CtrlF4              = $6100;     { ^F4                              }π  kb_AltF4               = $6B00;     { ALT F4                           }ππ  kb_F5                  = $3F00;     { F5                               }π  kb_ShiftF5             = $5800;     { SHIFT F5                         }π  kb_CtrlF5              = $6200;     { ^F5                              }π  kb_AltF5               = $6C00;     { ALT F5                           }ππ  kb_F6                  = $4000;     { F6                               }π  kb_ShiftF6             = $5900;     { SHIFT F6                         }π  kb_CtrlF6              = $6300;     { ^F6                              }π  kb_AltF6               = $6D00;     { ALT F6                           }ππ  kb_F7                  = $4100;     { F7                               }π  kb_ShiftF7             = $5A00;     { SHIFT F7                         }π  kb_CtrlF7              = $6400;     { ^F7                              }π  kb_AltF7               = $6E00;     { ALT F7                           }ππ  kb_F8                  = $4200;     { F8                               }π  kb_ShiftF8             = $5B00;     { SHIFT F8                         }π  kb_CtrlF8              = $6500;     { ^F8                              }π  kb_AltF8               = $6F00;     { ALT F8                           }ππ  kb_F9                  = $4300;     { F9                               }π  kb_ShiftF9             = $5C00;     { SHIFT F9                         }π  kb_CtrlF9              = $6600;     { ^F9                              }π  kb_AltF9               = $7000;     { ALT F9                           }ππ  kb_F10                 = $4400;     { F10                              }π  kb_ShiftF10            = $5D00;     { SHIFT F10                        }π  kb_CtrlF10             = $6700;     { ^F10                             }π  kb_AltF10              = $7100;     { ALT F1\0                         }ππ{ cursors ······························································ }ππ  kb_Up                  = $4800;     { UP                               }ππ  kb_Down                = $5000;     { DOWN                             }ππ  kb_Left                = $4B00;     { LEFT                             }π  kb_CtrlLeft            = $7300;     { ^LEFT                            }ππ  kb_Right               = $4D00;     { RIGHT                            }π  kb_CtrlRight           = $7400;     { ^RIGHT                           }ππ  kb_Home                = $4700;     { HOME                             }π  kb_CtrlHome            = $7700;     { ^HOME                            }ππ  kb_End                 = $4F00;     { END                              }π  kb_CtrlEnd             = $7500;     { ^END                             }ππ  kb_PgUp                = $4900;     { PG UP                            }π  kb_CtrlPgUp            = $8400;     { ^PG UP                           }ππ  kb_PgDown              = $5100;     { PG DN                            }π  kb_CtrlPgDown          = $7600;     { ^PG DN                           }ππ{ etc: keys ···························································· }ππ  kb_Esc                 = $011B;     { ESC                              }ππ  kb_Enter               = $1C0D;     { RETURN                           }π  kb_CtrlEnter           = $1C0A;     { ^ENTER                           }π                                      { LF - Line Feed                   }ππ  kb_BackSpace           = $0E08;     { BACKSPACE                        }π  kb_CtrlBackspace       = $0E7F;     { ^BACKSPACE                       }π                                      { DEL - Delete                     }ππ  kb_Tab                 = $0F09;     { TAB                              }π  kb_Shift_Tab           = $0F00;     { SHIFT TAB                        }ππ  kb_Ins                 = $5200;     { INSERT                           }ππ  kb_Del                 = $5300;     { DELETE                           }ππ  kb_45                  = $565C;     { Key 45                       [2] }π  kb_Shift45             = $567C;     { SHIFT KEY 45                 [2] }ππ  kb_CtrlPrtSc           = $7200;     { ^PRTSC                       [2] }ππ  kb_CtrlBreak           = $0000;     { ^BREAK                       [2] }ππππ{ footnotes ······························································ππ  [1] All key codes refers to Interrupt 16h Services 0 and 1,π      the "Standard Function", that works with all keyboards types.ππ  [2] These key codes are only availlable in the 101/102-key keyboard,π      the current IBM standard ("Enhanced") keyboard.ππ··········································································ππINT 16h,  00h (0)        Keyboard Read                                   allππ    Returns the next character in the keyboard buffer; if no character isπ    available, this service waits until one is available.ππ       On entry:      AH         00hππ       Returns:       AL         ASCII character codeπ                      AH         Scan codeππ  ──────────────────────────────────────────────────────────────────────────ππ       Notes:         The scan codes are the numbers representing theπ                      location of the key on the keyboard. As new keysπ                      have been added and the keyboard layout rearranged,π                      this numbering scheme has not been consistent withπ                      its original purpose.ππ                      If the character is a special character, then ALπ                      will be 0 and the value in AH will be the extendedπ                      scan code for the key.ππ                      Use the scan codes to differentiate between keysπ                      representing the same ASCII code, such as the plusπ                      key across the top of the keyboard and the gray plusπ                      key.ππ                      After the character has been removed from theπ                      keyboard buffer, the keyboard buffer start pointerπ                      (at 0:041Ah) is increased by 2. If the start pointerπ                      is beyond the end of the buffer, the start pointerπ                      is reset to the start of the keyboard buffer.ππ                      If no character is available at the keyboard, thenπ                      the AT, XT-286, and PC Convertible issue an INT 15h,π                      Service 90h (Device Busy), for the keyboard,π                      informing the operating system that there is aπ                      keyboard loop taking place and thereby allowing theπ                      operating system to perform another task.ππ                      After every character is typed, the AT, XT-286, andπ                      PC Convertible issue an INT 15h, Service 91hπ                      (Interrupt Complete). This allows the operatingπ                      system to switch back to a task that is waiting forπ                      a character at the keyboard.ππ                      See Service 10h for an equivalent service thatπ                      supports the enhanced (101/102-key) keyboard.ππ··········································································ππINT 16h,  01h (1)        Keyboard Status                                 allπ    Checks to see if a character is available in the buffer.ππ       On entry:      AH         01hππ       Returns:       Zero       0, if character is availableπ                                 1, if character is not availableπ                      AL         ASCII character code (if character isπ                                 available)π                      AH         Scan code (if character is available)ππ  ──────────────────────────────────────────────────────────────────────────ππ       Notes:         If a character is available, the Zero Flag isπ                      cleared and AX contains the ASCII value in AL andπ                      the scan code in AH. The character is not removedπ                      from the buffer. Use Service 00h to remove theπ                      character from the buffer. See Service 00h for aπ                      complete description of the meaning of AX if aπ                      character is available.ππ                      This service is excellent for clearing the keyboardπ                      or allowing a program to be interruptable by aπ                      specific key sequence.ππ                      See Service 11h for an equivalent service thatπ                      supports the enhanced (101/102-key) keyboard.ππ········································································ }ππππIMPLEMENTATIONπππEND. { HTkb.PAS }πππ                                  34     08-18-9312:27ALL                      JOSE ALMEIDA             Read a keyboard Key      IMPORT              9         { Reads a key from the keyboard buffer, removing it.π  Part of the Heartware Toolkit v2.00 (HTkey1.PAS) for Turbo Pascal.π  Author: Jose Almeida. P.O.Box 4185. 1504 Lisboa Codex. Portugal.π          I can also be reached at RIME network, site ->TIB or #5314.π  Feel completely free to use this source code in any way you want, and, ifπ  you do, please don't forget to mention my name, and, give me and Swag theπ  proper credits. }ππFUNCTION Get_Scan_Code : word;π{ DESCRIPTION:π    Reads a key from the keyboard buffer, removing it.π  SAMPLE CALL:π    NW := Get_Scan_Code;π  RETURNS:π    The next character in the keyboard buffer.π  NOTES:π    If no character is availlable, the service performed by this functionπ      waits until one is availlable. }ππvarπ  HTregs : registers;ππBEGIN { Get_Scan_Code }π  HTregs.AH := $00;π  Intr($16,HTregs);π  Get_Scan_Code := HTregs.AX;πEND; { Get_Scan_Code }π                                                                                                                              35     08-18-9312:27ALL                      JOSE ALMEIDA             Check Char Available     IMPORT              8         { Checks to see it a character is availlable in the DOS keyboard buffer.π  Part of the Heartware Toolkit v2.00 (HTkey1.PAS) for Turbo Pascal.π  Author: Jose Almeida. P.O.Box 4185. 1504 Lisboa Codex. Portugal.π          I can also be reached at RIME network, site ->TIB or #5314.π  Feel completely free to use this source code in any way you want, and, ifπ  you do, please don't forget to mention my name, and, give me and Swag theπ  proper credits. }ππFUNCTION Key_Ready : boolean;π{ DESCRIPTION:π    Checks to see it a character is availlable in the DOS keyboard buffer.π  SAMPLE CALL:π    B := Key_Ready;π  RETURNS:π    TRUE  : If there is a key waiting to be readed in the keyboard buffer;π    FALSE : If it is not. }ππvarπ  HTregs : registers;ππBEGIN { Key_Ready }π  HTregs.AH := $01;π  Intr($16,HTregs);π  Key_Ready := not (HTregs.Flags and FZero <> 0);πEND; { Key_Ready }π                  36     08-18-9312:27ALL                      JOSE ALMEIDA             Read Key - NO REMOVE     IMPORT              11        { Reads a key from the keyboard buffer, WITHOUT removing it.π  Part of the Heartware Toolkit v2.00 (HTkey1.PAS) for Turbo Pascal.π  Author: Jose Almeida. P.O.Box 4185. 1504 Lisboa Codex. Portugal.π          I can also be reached at RIME network, site ->TIB or #5314.π  Feel completely free to use this source code in any way you want, and, ifπ  you do, please don't forget to mention my name, and, give me and Swag theπ  proper credits. }ππFUNCTION Read_Key : word;π{ DESCRIPTION:π    Reads a key from the keyboard buffer, WITHOUT removing it.π  SAMPLE CALL:π    NW := Read_Key;π  RETURNS:π    The scan code of the key that is ready to be readen from the buffer, or,π      if there is no key in the buffer, returns $FFFF value.π  NOTES:π    This is a special function. It's only to be called in very specialπ      situations. It checks if a key is ready in the keyboardπ      buffer. If there is a key, then the key is readed but NOT removedπ      from the buffer. The key will remain in the buffer. }ππvarπ  HTregs : registers;ππBEGIN { Read_Key }π  HTregs.AH := $01;π  Intr($16,HTregs);π  if not (HTregs.Flags and FZero <> 0) thenπ    Read_Key := HTregs.AXπ  elseπ    Read_Key := $FFFF;πEND; { Read_Key }π                                                                         37     08-27-9321:29ALL                      WILBERT VAN LEIJEN       Trapping ALT and CTRL    IMPORT              13        {πWILBERT VAN LEIJENππ> HEy, I have been using some routines to check if certain keys are pressed,π> but I can't figure out how to test For ALT and CTRL key combinations.π}ππ{$G+}ππUsesπ  Dos, Crt;ππVarπ  KeyHandlerProc : Procedure;π  Int15Vector    : Pointer;ππConstπ  AltStatus  : Array [Boolean] of String[5] = ('     ', ' ALT ');π  CtrlStatus : Array [Boolean] of String[6] = ('      ', ' CTRL ');ππProcedure KeyHandler; Far;πVarπ  AltKey  : Boolean;π  CtrlKey : Boolean;π  WhereXY : Recordπ    x, y : Byte;π  end;ππbeginπ  AltKey  := False;π  CtrlKey := False;ππ  Asmπ    MOV AH, 2π    INT 16hπ    CMP AL, 8π    JNE @1π    INC [AltKey]π   @1:π    CMP AL, 4π    JNE @2π    INC [CtrlKey]π   @2:π  end;ππ  WhereXY.x := WhereX;π  WhereXY.y := WhereY;π  GotoXY(66, 25);π  Write(AltStatus[AltKey], ' ', CtrlStatus[CtrlKey]);π  GotoXY(WhereXY.x, WhereXY.y);πend;  { KeyHandler }ππ{ This INT 15h handler is called every time a key is pressed -π  provided you're not running this Program on an XT-class machine }ππProcedure TrapKeyboard; Assembler;πAsmπ  PUSH   BXπ  PUSH   DSπ  PUSHFπ  MOV    BX, SEG @Dataπ  MOV    DS, BXπ  CMP    AH, 4Fhπ  JNE    @ChainInt15π  PUSH   ESπ  PUSHAπ  CALL   [KeyHandlerProc]π  POPAπ  POP    ESππ @ChainInt15:π  PUSHFπ  CALL   [Int15Vector]π  POPFπ  POP    DSπ  POP    BXπ  IRETπend;  { TrapKeyboard }ππbeginπ  GetIntVec($15, Int15Vector);π  KeyHandlerProc := KeyHandler;π  SetIntVec($15, @TrapKeyboard);π  ReadLn;π  SetIntVec($15, Int15Vector);πend.π                                                         38     08-27-9321:30ALL                      INGO ROHLOFF             Detect Keys DOWN         IMPORT              12        { INGO ROHLOFFππ> I've got a problem I just CAN'T solve...π> In a PASCAL-program I want to execute a procedure every time the userπ> presses a key... Fairly easy, right ? But here comes the problem : I wantπ> to repeat that procedure until he RELEASES that key...ππThe only way to do that is to hook up the int 9 (the Keyoard Int...).π}ππProgram KEY;ππusesπ  crt, dos;ππvarπ  oldint  : pointer;π  keydown : byte;π  keys    : array [0..127] of boolean;π  scan,π  lastkey : byte;ππprocedure init;πvarπ  i : byte;πbeginπ  clrscr;π  for i := 0 to 127 doπ    keys[i] := false;   {No keys pressed}π  keydown := 0;πend;ππprocedure INT9; interrupt;πbeginπ  scan := port[$60];     { Get Scancode }π  if scan > $7F then     { Key released ? }π  beginπ    if keys[scan xor $80] thenπ      dec(keydown);π    keys[scan xor $80] := false;   {Yes !}π  endπ  elseπ  beginπ    if not keys[scan] thenπ      inc(keydown);π    keys[scan] := true;  {NO ! Key pressed }π    lastkey := scan;π  end;π  port[$20] := $20;  { Send EndOfInterrupt to Interruptcontroller }πend;ππbeginπ  init;π  getintvec(9, oldint);π  setintvec(9, @INT9);π  repeatπ    if (keydown > 0) and not keys[1] thenπ    beginπ      repeatπ        sound(lastkey * 30);π      until keydown = 0;π      nosound;π    end;π  until keys[1];        {*** Wait for ESC pressed ***}π  setintvec(9, oldint);πend.π                                                             39     08-27-9321:30ALL                      PER-ERIC LARSSON         Klick on keypress        IMPORT              4         {πPER-ERIC LARSSONππ> How do you determine if a key is still held down after another isπ> pressed ? KeyPressed returns False after second key is pressed and firstπ> key is still held down. ??ππFrom the helpFile For KEEP :π}ππProcedure Keyclick; interrupt;πbeginπ  if Port[$60] < $80 thenπ    { Only click when key is pressed }π                                                         40     08-27-9321:30ALL                      TOM MOORE                Sound with Keys          IMPORT              6         {πTOM MOOREππ> In a PASCAL-Program I want to execute a Procedure every time theπ> user presses a key... Fairly easy, right ? But here comes theπ> problem : I want to Repeat that Procedure Until he RELEASES thatπ> key...π}ππUsesπ  Crt;πConstπ  Done : Boolean = False;πVarπ  Ch : Char;πππProcedure MakeSound;πbeginπ  if Port[$60] < $80 thenπ  beginπ    Sound(220);π    Delay(100);π  end;π  if port[$60] >  $80 thenπ    NoSound;πend;ππbeginπ  Repeatπ    Repeatπ    { While waiting For KeyPressed }π    Until KeyPressed;ππ    ch := ReadKey;π    if ch = #27 then halt;π      makeSound;π  Until Done;πend.π                                        41     08-27-9321:31ALL                      ROB PERELMAN             Getting Key Stats        IMPORT              10        { ROB PERELMAN }ππUnit KeyStats;ππInterfaceππFunction RightShift : Boolean;πFunction LeftShift  : Boolean;πFunction Control    : Boolean;πFunction Alt        : Boolean;πFunction ScrollLock : Boolean;πFunction NumLock    : Boolean;πFunction CapsLock   : Boolean;πFunction Insert     : Boolean;ππImplementationππUsesπ  Dos;ππFunction ShiftState : Byte;πVarπ  Regs : Registers;πbeginπ  Regs.Ah := 2;π  Intr($16, Regs);π  ShiftState := Regs.Al;πend;ππFunction RightShift : Boolean;πbeginπ  RightShift := (ShiftState and 1) <> 0;πend;ππFunction LeftShift : Boolean;πbeginπ  LeftShift := (ShiftState and 2) <> 0;πend;ππFunction Control : Boolean;πbeginπ  Control := (ShiftState and 4) <> 0;πend;ππFunction Alt : Boolean;πbeginπ  Alt := (ShiftState and 8) <> 0;πend;ππFunction ScrollLock : Boolean;πbeginπ  ScrollLock := (ShiftState and 16) <> 0;πend;ππFunction NumLock : Boolean;πbeginπ  NumLock := (ShiftState and 32) <> 0;πend;ππFunction CapsLock : Boolean;πbeginπ  CapsLock := (ShiftState and 64) <> 0;πend;ππFunction Insert : Boolean;πbeginπ  Insert := (ShiftState and 128) <> 0;πend;ππend.π                                                               42     08-27-9321:31ALL                      SEAN PALMER              Stuffing Keyboard        IMPORT              14        {πSEAN PALMERππ>> I am assuming you already have a buffer-stuffer that takes a char and aπ>> scan code as input, so I won't post mine.ππ>No, I don't have a keyboard buffer-stuffer.ππYou said you wanted one that DIDN'T need you to tell it what a char'sπscancode was. Well, this would basically require a lookup table ofπpossible scancodes for each ascii char... Plus some that don't haveπcorresponding scancodes. What you could try is to just send a null (#0)πto the routine as a scan code, I believe that's what happens when youπenter a keystroke using the Alt-Numeric Keypad method... so it'd work asπlong as the program you're sending the keys to doesn't need theπscancode.ππHere's an untested version of the method that other guy sent to you...:π}ππprocedure stuffKey(c : char; scan : byte); assembler;πasmπ  mov cl, cπ  mov ch, scanπ  mov ah, 5π  int $16π  {al=0 if success, 1 if failed, but we just ignore that here}πend;ππso here's a call that just assumes a 0 scan codeππprocedure stuffChar(c : char); assembler;πasmπ  mov cl,cπ  xor ch,chπ  mov ah,5π  int $16πend;ππ{πIf you don't wanna go through the BIOS you can do it directly like this:π(plus this is 'pure' Turbo Pascal code.. 8) }ππvarπ  head     : word absolute $40 : $1A;π  tail     : word absolute $40 : $1C;π  bufStart : word absolute $40 : $80;π  bufEnd   : word absolute $40 : $82;ππprocedure stuffKey(c : char; scan : byte);πbeginπ  memW[$40 : tail] := word(scan) shl 8 + byte(c);π  inc(tail, 2);π  if tail = bufEnd thenπ    tail := bufStart;πend;ππprocedure clearBuffer;πbeginπ  tail := head;πend;πππ                                                                                            43     08-27-9321:32ALL                      STEVEN TALLENT           Locking the Keyboard     IMPORT              9         {πSTEVEN TALLENTππYou can disable the whole keyboard like this:ππSample program by Kerry Sokalskyπ}ππUsesπ  KScreen;ππProcedure KeyboardEnable; {unlocks keyboard}πbeginπ  Port[$21] := Port[$21] and 253;π end;ππProcedure KeyboardDisable; {locks keyboard}πbeginπ  Port[$21] := Port[$21] or 2;πend;ππVarπ  X : Integer;ππbeginπ  ClrScr;ππ  KeyboardDisable;ππ  For X := 1 to 10000 doπ  beginπ    GotoXY(1,1);π    Write(X);π    If Keypressed thenπ    beginπ      ClearBuffer;π      gotoxy(10,10);π      write('This should never occur! - ', X);π    end;π  end;ππ  ClearBuffer; { This is here because even though the keyboard is turned off,π                 each key is still placed in the buffer }π  KeyboardEnable;ππ  For X := 1 to 15000 doπ  beginπ    GotoXY(1,1);π    Write(X);π    If Keypressed thenπ    beginπ      ClearBuffer;π      gotoxy(10,10);π      write('This could occur! - ', X);π    end;π  end;ππend.                                                                                                                    44     08-27-9321:49ALL                      SEAN PALMER              Another Readkey          IMPORT              9         {πSEAN PALMERππ>I want to be able to transparently read a keypress.  Inπ>other Words, I'd like to know what key is being pressed,π>but allow the keypress to return to the keyboard buffer orπ>to be read by the Program that's reading it.  I'd like thisπ>to Function as a TSR, and I need some way to Record theπ>keypresses.  This is a very complicated problem which Iπ>have consulted many advanced Programmers With.  Please helpπ>if you are able.  Thanks in advance!ππIt returns the Character part of the Char/scan code combo in the currentπhead of the keyboard buffer queue in the bios data area.πThe scan code would be at the location $40:head+1.ππIt would probably be more efficient if you used $0:$41A instead ofπ$40:$1A, but that might cause problems With protected mode.π}ππVarπ  head : Word Absolute $40 : $1A;π  tail : Word Absolute $40 : $1C;ππFunction peekKey : Char;πbeginπ  if head = tail thenπ    peekKey := #0π  elseπ    peekKey := Char(mem[$40 : head]);πend;ππ                                                    45     11-02-9305:29ALL                      BO KALTOFT               Disable Ctrl-Break       SWAG9311            6         {πBO KALTOFTππ> How can i disable the Pascal interrupt key Ctrl-Break?π}ππConstπ  BreakKey : Boolean = False;π  BreakOff : Boolean = False;πVarπ  BreakSave : Pointer;ππ{$F+}πProcedure BreakHandler; Interrupt;πbeginπ  BreakKey := True;πend;π{$F-}πππProcedure CBOff;πbeginπ  GetIntVec($1B, BreakSave);π  SetIntVec($1B, Addr(BreakHandler));π  BreakOff := True;πend;ππProcedure CBOn;πbeginπ  SetIntVec($1B, BreakSave);π  BreakOff := False;πend;ππbeginπ  BreakSave := Nil;π  CBOff; {disable}π  .π  .π  .π  CBOn;  {enable}πend.ππ                                                                                                                     46     11-02-9305:58ALL                      JAN DOGGEN               a VERY Complete KB Unit  SWAG9311            123       Unit KeybFAQ;π(* This is version 0.90 of KEYBFAQ, a Unit that answers two questionsπ * often asked in the Pascal message area's:π * - How do I change my cursor ?π * - How can I perform input of String With certain limitationsπ *   (such as 'maximum length', 'only numbers' etc.)π *π * I will distribute this Unit *ONCE* in message form (three messages)π * because it takes up 500 lines of code. It is untested code, cut fromπ * my Unit library, and distributed *as is* With no other documentationπ * than these initial lines. You can use this code in your apps as you like,π * and you can redistribute it, provided you:π * - redistribute *source* code;π * - do not Charge anything For the source code;π * - give me credit For the original code if you change anything;π * - keep this 'documentation' With it.π * (Loosely translated: common decency is enough)π * Copyright will formally remain mine.π *π * Please do not respond about this code. I am going away For a few weeksπ * and will distribute version 1.0 in ZIP form after that. That packageπ * will have *tested* code, docs and examples.π *π * Some notes about this code:π * - Use it always, or don't use it. I.e. if you start using GetKeyπ *   you should use that throughout your Program, and drop all ReadKeys.π * - The redefinition of Char into Key has two reasons:π *   - it allows better Type checkingπ *   - it allows future changes to the internal representation of theπ *     Key Type (I plan to make it a Word Type to handle the overlapπ *     in key definitions that is still present, and/or adapt Unicodeπ *     Character definitions)π * - The overlap in the Constant key definitions may lookπ *   problematic, but in the years I have been using this, it has notπ *   posed any problems, generally because you only allow those keysπ *   that have a meaning For your app.π *π * Happy Pascalling,π * Jan Doggen, 27/8/93 *)ππInterfaceππTypeπ  Key    = Char;π  KeySet = Set of Key;π  (* See later in this Interface section For defined sets *)ππVarπ  BlankChar : Char;    (* Char used by GetStr to fill the bar; default ' ' *)ππProcedure FlushKeyBuf;π(* Clears the BIOS keyboard buffer *)ππFunction  InsertStatus : Boolean;πProcedure SetInsertStatus(On : Boolean);ππProcedure NiceBeep;π(* Replaces the system beep With a more pleasant one. *)ππTypeπ  CursType = (NOCUR, LINECUR, BLOCKCUR);ππProcedure SetCursor(CType: CursType);π(* SetCursor sets a block or line cursor, or no cursor. *)ππFunction GetVidMode : Byte;π(* Return BIOS video mode *)ππFunction MonoChrome(Vmode : Byte) : Boolean;π(* Returns True if a monochrome video mode is specified *)ππFunction WinLeft   : Byte;πFunction WinRight  : Byte;πFunction WinTop    : Byte;πFunction WinBottom : Byte;π(* Return Absolute co-ordinates of current Window *)ππFunction RepeatStr(Str : String; N : Integer) : String;π(* Returns a String consisting of <N> repetitionsof <Str>. *)ππFunction GetKey : Key;π(* Returns a Variable of Type Key; see the table below For the definitions.π * GetKey also accepts the <Alt-numeric keypad> ASCII codes. *)ππVarπ  ClearOnFirstChar,π  WalkOut,π  StartInFront : Boolean;π (* These Booleans influence the way in which GetStr operates:π  *π  * With WalkOut = True: the left and right arrow keys also act as ExitKeysπ  * when they bring us 'outside' of the Word (we Exit the Procedure).π  *π  * With ClearOnFirstChar = True: if the first key Typed is a Character,π  * the initial Str is cleared.π  *π  * With StartInFront = True: the cursor will be positioned at the firstπ  * Character when we start the Procedure (instead of after the last)π  *π  * Default settings For these Booleans are False. *)ππProcedure GetStr(Xpos, Ypos,π                 MaxLen,π                 Ink, Paper   : Byte;π                 AllowedKeys,π                 ExitKeys     : KeySet;π                 BeepOnError  : Boolean;π                 Var Str      : String;π                 Var ExitKey  : Key);π(* Reads a String of max. <MaxLen> Characters starting at relative positionπ * <XPos,YPos>. A bar of length <MaxLen> is placed there With colorsπ * <Ink> on <Paper>. An initial value For the String returned can beπ * passed With <Str>.π *π * - BeepOnError indicates audio feedback on incorrect keypressesπ * - AllowedKeys is a set of Keys that may be entered. if AllowedKeys = [],π *   all keys are allowed.π * - ExitKeys is a set of Keys that stop the Procedure; <Str> will thenπ *   contain the edited String and <ExitKey> will be key that made us Exit.π *   if ExitKeys is [], it will be replaced by [Enter,Escape].π *   The keys you specify in ExitKeys, do not have to be specified inπ *   AllowedKeys. *)ππFunction WaitKey(LegalKeys : Keyset; Flush : Boolean) : Key;π(* Waits For one of the keys in LegalKeys to be pressed, then returns this.π * if <Flush> = True, the keyboard buffer is flushed first. *)ππConstπ  Null      = #0;    CtrlA = #1;   F1       = #187;  Home       = #199;π  BSpace    = #8;    CtrlB = #2;   F2       = #188;  endKey     = #207;π  Tab       = #9;    CtrlC = #3;   F3       = #189;  PgUp       = #201;π  Lfeed     = #10;   CtrlD = #4;   F4       = #190;  PgDn       = #209;π  Ffeed     = #12;   CtrlE = #5;   F5       = #191;  Left       = #203;π  CReturn   = #13;   CtrlF = #6;   F6       = #192;  Right      = #205;π  Escape    = #27;   CtrlG = #7;   F7       = #193;  Up         = #200;π  ShiftTab  = #143;  CtrlH = #8;   F8       = #194;  Down       = #208;π  CtrlPrtsc = #242;  CtrlI = #9;   F9       = #195;  Ins        = #210;π  Enter     = #13;   CtrlJ = #10;  F10      = #196;  Del        = #211;π  Esc       = #27;   CtrlK = #11;  ShiftF1  = #212;  CtrlLeft   = #243;π  Space     = #32;   CtrlL = #12;  ShiftF2  = #213;  CtrlRight  = #244;π                     CtrlM = #13;  ShiftF3  = #214;  CtrlendKey = #245;π  { Note the     }   CtrlN = #14;  ShiftF4  = #215;  CtrlPgdn   = #246;π  { overlap of   }   CtrlO = #15;  ShiftF5  = #216;  CtrlPgup   = #127;π  { Ctrl-keys    }   CtrlP = #16;  ShiftF6  = #217;  CtrlHome   = #247;π  { and others ! }   CtrlQ = #17;  ShiftF7  = #218;π                     CtrlR = #18;  ShiftF8  = #219;π                     CtrlS = #19;  ShiftF9  = #220;π                     CtrlT = #20;  ShiftF10 = #221;π                     CtrlU = #21;  CtrlF1   = #222;π                     CtrlV = #22;  CtrlF2   = #223;π                     CtrlW = #23;  CtrlF3   = #224;π                     CtrlX = #24;  CtrlF4   = #225;π                     CtrlY = #25;  CtrlF5   = #226;π                     CtrlZ = #26;  CtrlF6   = #227;π                     AltQ  = #144; CtrlF7   = #228;π                     AltW  = #145; CtrlF8   = #229;π                     AltE  = #146; CtrlF9   = #230;π                     AltR  = #147; CtrlF10  = #231;π                     AltT  = #148; AltF1    = #232;π                     AltY  = #149; AltF2    = #233;π                     AltU  = #150; AltF3    = #234;π                     AltI  = #151; AltF4    = #235;π                     AltO  = #152; AltF5    = #236;π                     AltP  = #153; AltF6    = #237;π                     AltA  = #158; AltF7    = #238;π                     AltS  = #159; AltF8    = #239;π                     AltD  = #160; AltF9    = #240;π                     AltF  = #161; AltF10   = #241;π                     AltG  = #162;π                     AltH  = #163;π                     AltJ  = #164;π                     AltK  = #165;π                     AltL  = #166; Alt1     = #248;π                     AltZ  = #172; Alt2     = #249;π                     AltX  = #173; Alt3     = #250;π                     AltC  = #174; Alt4     = #251;π                     AltV  = #175; Alt5     = #252;π                     AltB  = #176; Alt6     = #253;π                     AltN  = #177; Alt7     = #254;π                     AltM  = #178; Alt8     = #255;  { No Alt9 or Alt0 ! }ππ{ SETS }π  LetterKeys   : KeySet = ['A'..'Z','a'..'z'];π  SpecialKeys  : KeySet =π    ['!','?','b','a','a','a','a','a','A','a','A','A','e','e','e',π     'e','E','i','i','i','i','o','o','o','o','o','O','u','u','u',π     'u','U','c','C','n','N'];π  UpKeys       : KeySet = ['A'..'Z'];π  LowKeys      : KeySet = ['a'..'z'];π  VowelKeys    : KeySet = ['a','e','i','o','u','A','E','I','O','U'];π  DigitKeys    : KeySet = ['0'..'9'];π  OperatorKeys : KeySet = ['*','/','+','-'];π  YNKeys       : KeySet = ['y','n','Y','N'];π  JNKeys       : KeySet = ['j','n','J','N'];π  BlankKeys    : KeySet = [#0..#32];π  AllKeys      : KeySet = [#0..#255];π  FKeys        : KeySet = [F1..F10];π  ShiftFKeys   : KeySet = [ShiftF1..ShiftF10];π  AltFKeys     : KeySet = [AltF1..AltF10];π  CtrlFKeys    : KeySet = [CtrlF1..CtrlF10];π  AllFKeys     : KeySet = [F1..F10,ShiftF1..AltF10];ππImplementationππUses Crt,Dos;ππProcedure NiceBeep; (* Replaces the system beep With a more pleasant one. *)πbeginπ  Sound(300);π  Delay(15);π  NoSound;πend;πππProcedure FlushKeyBuf;πVarπ  Ch : Char;πbeginπ  While KeyPressed doπ    Ch := ReadKey;πend;πππFunction InsertStatus : Boolean;πVarπ  Regs : Registers;πbeginπ  Regs.AH := 2;π  Intr($16, Regs);π  InsertStatus := ((Regs.AL and 128) = 128);πend;πππProcedure SetInsertStatus(On: Boolean);πbeginπ  if ON thenπ    Mem[$0040:$0017] := Mem[$0040:$0017] or 128π  elseπ    Mem[$0040:$0017] := Mem[$0040:$0017] and 127;πend;πππFunction GetVidMode: Byte;πVarπ  Regs : Registers;πbeginπ  Regs.AH := $0F;π  Intr($10, Regs);π  GetVidMode := Regs.AL;πend;πππFunction MonoChrome(Vmode : Byte) : Boolean;πbeginπ  MonoChrome := (VMode in [0,2,5,6,7,15,17]);πend;πππFunction WinLeft : Byte;πbeginπ  WinLeft := Lo(WindMin) + 1;πend;πππFunction WinRight : Byte;πbeginπ  WinRight := Lo(WindMax) + 1;πend;πππFunction WinTop : Byte;πbeginπ  WinTop := Hi(WindMin) + 1;πend;πππFunction WinBottom : Byte;πbeginπ  WinBottom := Hi(WindMax) + 1;πend;πππFunction RepeatStr(Str : String; N : Integer) : String;πVarπ  Result : String;π  I, J,π  NewLen,π  Len    : Integer;πbeginπ  Len    := Length(Str);π  NewLen := N * Length(Str);π  Result[0] := Chr(NewLen);π  J := 1;π  For I := 1 to N DOπ  beginπ    Move(Str[1], Result[J], Len);π    Inc(J, Len);π  end;π  RepeatStr := Result;πend;πππProcedure SetCursor(CType : CursType);πVarπ  VM   : Byte;π  Regs : Registers;πbeginπ  VM := GetVidMode;π  With Regs DOπ  Case CType OFπ    NOCUR :π    beginπ      Regs.CX := $2000;      { Off-screen cursor position }π      Regs.AH := 1;π    end;ππ    LINECUR : beginπ      AX := $0100;π      BX := $0000;π      if MonoChrome(VM) thenπ        CX := $0B0Cπ      elseπ        CX := $0607π    end;ππ    BLOCKCUR :π    beginπ      AX := $0100;π      BX := $0000;π      if MonoChrome(VM) thenπ        CX := $010Dπ      elseπ        CX := $0107;π    end;π  end;π  Intr($10, Regs);πend;πππFunction GetKey : Key;πVarπ  Ch : Char;πbeginπ  Ch := ReadKey;π  if Ch = #0 thenπ  beginπ    Ch := ReadKey;π    if Ch <= #127 thenπ      GetKey := Chr(Ord(Ch) or $80)π    elseπ    if Ch = #132 thenπ      GetKey := CtrlPgUpπ    elseπ      GetKey := Null;π  endπ  elseπ    GetKey := Ch;πend;ππProcedure GetStr(XPos, YPos, MaxLen, Ink, Paper : Byte; AllowedKeys,π                 ExitKeys : KeySet; BeepOnError : Boolean;π                 Var Str : String; Var ExitKey : Key);πVarπ  CursPos,π  LeftPos,π  TopPos,π  RightPos,π  BottomPos,π  X, Y        : ShortInt;π  InsFlag,π  OAFlag,π  FirstKey    : Boolean;π  InKey       : Key;π  OldTextAttr : Byte;π  OldWindMin,π  OldWindMax  : Word;ππ  Procedure CleanUp;π  { Second level; called when we leave }π  beginπ    WindMin  := OldWindMin;π    WindMax  := OldWindMax;π    TextAttr := OldTextAttr;π    ExitKey  := InKey;π  end;ππbeginπ  LeftPos   := WinLeft;π  RightPos  := WinRight;π  TopPos    := WinTop;π  BottomPos := WinBottom;π  X         := XPos + LeftPos - 1;π  Y         := YPos + TopPos - 1;π  InsFlag   := InsertStatus;π  if ExitKeys = [] thenπ    ExitKeys := [Enter, Escape];π  if AllowedKeys = [] thenπ    AllowedKeys := AllKeys;π (* Save old settings here; restore them in proc CleanUp when Exiting *)π  OldWindMin := WindMin;π  OldWindMax := WindMax;π  WindMin := 0;             { Set Absolute Window co-ordinates and     }π  WindMax := $FFFF;         { prevent scroll at lower right Character. }π  OldTextAttr := TextAttr;π  TextAttr := ((Paper SHL 4) or Ink) and $7F;π  { Note: the 'AND $F' ensures that blink is off }π  if StartInFront thenπ    CursPos := 1π  elseπ  if Length(Str)+1 < MaxLen thenπ    CursPos := Length(Str) + 1π  elseπ    CursPos := MaxLen;π  FirstKey := True;π  if InsFlag thenπ    SetCursor(BLOCKCUR)π  elseπ    SetCursor(LINECUR);π  Repeatπ    if CursPos < 1 thenπ      if WalkOut thenπ      beginπ        CleanUp;π        Exit;π      endπ      elseπ      if BeepOnError thenπ      beginπ        NiceBeep;π        CursPos := 1;π      end;ππ    if (CursPos > Length(Str) + 1) thenπ      if WalkOut thenπ      beginπ        CleanUp;π        Exit;π      endπ      elseπ      if BeepOnError thenπ      beginπ        NiceBeep;π        CursPos := Length(Str) + 1;π      end;ππ    if CursPos > MaxLen thenπ      if WalkOut and (InKey = Right) thenπ      beginπ        CleanUp;π        Exit;π      endπ      elseπ      beginπ        if BeepOnError thenπ          NiceBeep;π        CursPos := MaxLen;π      end;ππ    GotoXY(X, Y);π    Write(Str + RepeatStr(BlankChar, MaxLen - Length(Str)));π    GotoXY(X + CursPos - 1, Y);π    InKey := GetKey;ππ    if InKey in ExitKeys thenπ    beginπ      CleanUp;π      Exit;π    end;ππ    Case InKey OFπ      Left              : Dec(CursPos);π      Right             : Inc(CursPos);π      CtrlLeft, Home    : CursPos := 1;π      CtrlRight, endKey : CursPos := Length(Str) + 1;π      Tab               : Inc(CursPos,8);π      ShiftTab          : Dec(CursPos,8);ππ      Ins :π      beginπ        InsFlag := not InsFlag;π        if InsFlag thenπ          SetCursor(BLOCKCUR)π        elseπ          SetCursor(LINECUR);π      end;ππ      Del :π      if CursPos > Length(Str) thenπ      beginπ        if BeepOnError thenπ          NiceBeep;π      endπ      elseπ        Delete(Str, CursPos, 1);ππ      BSpace :π      if CursPos = 1 thenπ        if Length(Str) = 1 thenπ          Str := ''π        elseπ        beginπ          if BeepOnError thenπ            NiceBeep;π        endπ        elseπ        beginπ          Delete(Str, CursPos - 1, 1);π          Dec(CursPos);π        end;π      elseπ      beginπ        (* Note that 'AllowedKeys' that also have aπ        * meaning as a control key have already beenπ        * processed, so they will not be handled here. *)π        if InKey in AllowedKeys thenπ        beginπ          if ClearOnFirstChar and FirstKey thenπ          beginπ            Str     := '';π            CursPos := 1;π          end;π          if (CursPos = MaxLen) thenπ          beginπ            Str[CursPos] := InKey;π            Str[0]       := Chr(MaxLen);π          endπ          elseπ          if InsFlag thenπ          beginπ            Insert(InKey,Str,CursPos);π            if Length(Str) > MaxLen thenπ              Str[0] := Chr(MaxLen);π          endπ          elseπ          beginπ            Str[CursPos] := InKey;π            if CursPos > Length(Str) thenπ              Str[0] := Chr(CursPos);π          end;ππ          Inc(CursPos);π        endπ        elseπ        if BeepOnError thenπ          NiceBeep;π      end;π    end;ππ    FirstKey := False;π  Until 0 = 1;πend;πππFunction WaitKey(LegalKeys : Keyset; Flush : Boolean) : Key;πVarπ  K : Key;πbeginπ  if Flush thenπ    FlushKeybuf;π  Repeatπ    K := GetKey;π  Until K in LegalKeys;π  WaitKey := K;πend;πππbeginπ  BlankChar        := ' ';π  WalkOut          := False;π  ClearOnFirstChar := False;π  StartInFront     := False;πend.π     47     11-02-9310:27ALL                      LOU DUCHEZ               Disable Ctrl-Break       SWAG9311            17        (*πLOU DUCHEZππ>> How can i disable the Pascal interrupt key Ctrl-Break?ππ>Try CheckBreak := False;ππ> Isn't there another way to do this that works better? Just wondering... :)ππWell, here's some code I came up With.  What it does is "cheat": itπdetects if you're pressing "C" While "Ctrl" is down.  if so, it changesπ"Ctrl" to "undepressed".  As For "Ctrl-Break", I just changed theπbuilt-in "Ctrl-Break" interrupt to an "empty" routine (i.e., it doesπNOTHING).  And it's a TSR, too; to "un-TSR" the code, remove theπ"{$M ...}" at the beginning and the "keep(0)" at the end, then justπincorporate the code into your Programs.  More comments as I go:π*)ππ{$M $0400, $0000, $0000}π{$F+}ππProgram nobreak;πUsesπ  Dos;ππConstπ  ctrlByte = $04;  { Memory location $0040:$0017 governs the statUses ofπ                     the Ctrl key, Alt, Shifts, etc.  the "$04" bitπ                     handles "Ctrl". }ππVarπ  old09h       : Procedure; { original keyboard handler }π  ctrldown,π  cdown        : Boolean;π  keyboardstat : Byte Absolute $0040:$0017;    { the aforementioned location }ππProcedure new1bh; interrupt;  { new Ctrl-Break handler: does NOTHING }πbeginπend;ππProcedure new09h; interrupt;  { new keyboard handler: it checks if you'veπ                                pressed "C" or "Brk"; if you have, it changesπ                                "Ctrl" to "undepressed.  Then it calls theπ                                "old" keyboard handler. }πbeginπ  if port[$60] and $1d = $1d thenπ    ctrldown := (port[$60] < 128);π  if port[$60] and $2e = $2e thenπ    cdown := (port[$60] < 128);π  if cdown and ctrldown thenπ    keyboardstat := keyboardstat and not ctrlByte;π  Asmπ    pushfπ  end;π  old09h;πend;ππbeginπ  getintvec($09, @old09h);π  setintvec($09, @new09h);  { set up new keyboard handler }π  setintvec($1b, @new1bh);  { set up new "break" handler }π  ctrldown := False;π  cdown    := False;π  keep(0);πend.π                                                                                                                             48     10-28-9311:28ALL                      MARC BIR                 Clear Keyboard QUICK     SWAG9311            6         (*==========================================================================πDate: 08-25-93 (00:32)πFrom: MARC BIRπSubj: CLEAR KEYBOARDππ  Here's a quick way to clear keyboard buffer:π*)ππProcedure ClearKeyBoard;πBeginπ ASM CLI End;π MemW[$40:$1A] := MemW[$40:$1C];π ASM STI End;πEnd;ππ(*πMemW[$40:$1A] = ptr to next char in cyclical kbd bufferπMemW[$40:$1C] = ptr to last char ""ππ  Incase you haven't had data structures, when the next ptr equals theπlast ptr in a cyclical buufer, the buffer is empty.π  Hope that helps  ( doesn't need CRT )ππ                                                                                              49     09-26-9310:53ALL                      MARC BIR                 Keyboard Simulation      SWAG9311            10        (*πFrom: MARC BIRπSubj: KEYBOARD Simulationππ{BW>Ok, here is my problem...I am trying to read a string from aπfile, poke it i the keyboard buffer, and then dump the contents ofπthe buffer, so as to simulate that the user actually typed theπstring...This way the user doesnt have to type it all out..Myπprogram works fine, except if the string is more than characters, andπif I try to clear the buffer after 16 characters, all I get the lastπfew characters in the string..Can anyone please help?  I would realπlike to finish this dang project! :>  Thank you.}ππ{This should work, tested it out.  If it returns a false, you have toπstop sending characters, until those that are in the buffer are used,πdoesn't matter what scancode is if you don't use, ditto for asciicode }π*)ππFunction SimulateKey( AsciiCode, ScanCode : Byte ) : Boolean; AssemblerπAsmπ Mov  AH, 05Hπ Mov  CH, ScanCodeπ Mov  CL, AsciiCodeπ Int  16Hπ XOR  AX, 1       { bios returns 1 = error, 0 = false, pascal opposite }πEnd; { Returns false if buffer is full }π                                                                                                                           50     11-21-9309:36ALL                      MARK OUELLET             Flush/Stuff Keyboard     SWAG9311            6         {From: MARK OUELLET}π{ FLUSH/STUFF Keyboard w/INT21}ππPROGRAM StuffKbdTest;πuses dos;ππ  procedure FlushKbd; Assembler;ππ    asmπ      Mov AX, $0C00;π      Int 21h;π    end;ππ  procedure StuffKbd(S:string);ππ        varπ      Regs : registers;π      x : byte;π      BufferFull : boolean;ππ    beginπ      FlushKbd;π      Inc(S[0]);π      S[byte(S[0])] := #13;π      x := 1;π      repeatπ        Regs.AH := $05;π        Regs.CL := Byte(S[x]);π        Intr($16, Regs);π        BufferFull := boolean(Regs.AL);π        inc(x);π      until BufferFull or (x>byte(S[0]));π    end;ππ  beginπ        StuffKbd('Dir C:\');π  end.π                     51     09-26-9309:11ALL                      MARTIN RICHARDSON        Check for *ANY* Key      SWAG9311            7         {*****************************************************************************π * Function ...... IsKeyPressedπ * Purpose ....... To determine if *ANY* key is pressed on the keyboardπ * Parameters .... Noneπ * Returns ....... TRUE if a key is being pressedπ * Notes ......... Even returns TRUE if a shift/ctrl/alt/caps lock key is π *                 pressed.π * Author ........ Martin Richardsonπ * Date .......... May 13, 1992π *****************************************************************************}πFUNCTION IsKeyPressed: BOOLEAN;πBEGINπ     IsKeyPressed := ((MEM[$40:$17] AND $0F) > 0) OR (MEM[$40:$18] > 0)π                     OR KEYPRESSED;πEND;ππ                                                                                                           52     09-26-9308:47ALL                      MARTIN RICHARDSON        Clear keyboard buffer    SWAG9311            5         {****************************************************************************π * Procedure ..... ClearKBBufferπ * Purpose ....... To clear the keyboard buffer of pending keystrokesπ * Parameters .... Noneπ * Returns ....... N/Aπ * Notes ......... Noneπ * Author ........ Martin Richardsonπ * Date .......... May 13, 1992π ****************************************************************************}πPROCEDURE ClearKBBuffer;πBEGINπ     WHILE KEYPRESSED DO IF ReadKey = #0 THEN;πEND;π                             53     09-26-9309:12ALL                      MARTIN RICHARDSON        Keyboard Constants       SWAG9311            27        {** Keyboard Constant Codes **}ππCONSTπ     K_LEFT         = #75;        K_RIGHT        = #77;π     K_UP           = #72;        K_DOWN         = #80;π     K_HOME         = #71;        K_END          = #79;π     K_PGUP         = #73;        K_PGDN         = #81;π     K_DEL          = #83;        K_INS          = #82;π     K_ENTER        = #13;        K_ESC          = #27;π     K_BACKSPACE    = #8;         K_TAB          = #9;ππ     K_SPACE        = #32;        K_SHIFT_TAB    = #15;ππ     K_CTRL_LEFT    = #115;       K_CTRL_RIGHT   = #116;π     K_CTRL_PGUP    = #132;       K_CTRL_PGDN    = #118;π     K_CTRL_HOME    = #119;       K_CTRL_END     = #117;π     K_CTRL_ENTER   = #10;ππ     K_F1           = #59;        K_F2           = #60;π     K_F3           = #61;        K_F4           = #62;π     K_F5           = #63;        K_F6           = #64;π     K_F7           = #65;        K_F8           = #66;π     K_F9           = #67;        K_F10          = #68;ππ     K_SHIFT_F1     = #84;        K_SHIFT_F2     = #85;π     K_SHIFT_F3     = #86;        K_SHIFT_F4     = #87;π     K_SHIFT_F5     = #88;        K_SHIFT_F6     = #89;π     K_SHIFT_F7     = #90;        K_SHIFT_F8     = #91;π     K_SHIFT_F9     = #92;        K_SHIFT_F10    = #93;ππ     K_CTRL_F1      = #94;        K_CTRL_F2      = #95;π     K_CTRL_F3      = #96;        K_CTRL_F4      = #97;π     K_CTRL_F5      = #98;        K_CTRL_F6      = #99;π     K_CTRL_F7      = #100;       K_CTRL_F8      = #101;π     K_CTRL_F9      = #102;       K_CTRL_F10     = #103;ππ     K_ALT_F1       = #104;       K_ALT_F2       = #105;π     K_ALT_F3       = #106;       K_ALT_F4       = #107;π     K_ALT_F5       = #108;       K_ALT_F6       = #109;π     K_ALT_F7       = #110;       K_ALT_F8       = #111;π     K_ALT_F9       = #112;       K_ALT_F10      = #113;ππ     K_CTRL_A       = #1;         K_CTRL_B       = #2;π     K_CTRL_C       = #3;         K_CTRL_D       = #4;π     K_CTRL_E       = #5;         K_CTRL_F       = #6;π     K_CTRL_G       = #7;         K_CTRL_H       = #8;π     K_CTRL_I       = #9;         K_CTRL_J       = #10;π     K_CTRL_K       = #11;        K_CTRL_L       = #12;π     K_CTRL_M       = #13;        K_CTRL_N       = #14;π     K_CTRL_O       = #15;        K_CTRL_P       = #16;π     K_CTRL_Q       = #17;        K_CTRL_R       = #18;π     K_CTRL_S       = #19;        K_CTRL_T       = #20;π     K_CTRL_U       = #21;        K_CTRL_V       = #22;π     K_CTRL_W       = #23;        K_CTRL_X       = #24;π     K_CTRL_Y       = #25;        K_CTRL_Z       = #26;ππ     K_ALT_A        = #30;        K_ALT_B        = #48;π     K_ALT_C        = #46;        K_ALT_D        = #32;π     K_ALT_E        = #18;        K_ALT_F        = #33;π     K_ALT_G        = #34;        K_ALT_H        = #35;π     K_ALT_I        = #23;        K_ALT_J        = #36;π     K_ALT_K        = #37;        K_ALT_L        = #38;π     K_ALT_M        = #50;        K_ALT_N        = #49;π     K_ALT_O        = #24;        K_ALT_P        = #25;π     K_ALT_Q        = #16;        K_ALT_R        = #19;π     K_ALT_S        = #31;        K_ALT_T        = #20;π     K_ALT_U        = #22;        K_ALT_V        = #47;π     K_ALT_W        = #17;        K_ALT_X        = #45;π     K_ALT_Y        = #21;        K_ALT_Z        = #44;π                                                         54     09-26-9310:12ALL                      ROB PERELMAN             Complete Keyboard Unit   SWAG9311            30        (*πFrom: ROB PERELMANπSubj: A COMPLETE Keyboard Unit in ASMπ*)ππUNIT Keyboard;ππINTERFACEππ   FUNCTION AltPress: Boolean;π   FUNCTION CapsOn: Boolean;π   FUNCTION CtrlPress: Boolean;π   FUNCTION InsertOn: Boolean;π   FUNCTION LAltPress: Boolean;π   FUNCTION LCtrlPress: Boolean;π   FUNCTION LShiftPress: Boolean;π   FUNCTION NumOn: Boolean;π   FUNCTION RAltPress: Boolean;π   FUNCTION RCtrlPress: Boolean;π   FUNCTION RShiftPress: Boolean;π   FUNCTION ScrollOn: Boolean;π   FUNCTION ShiftPress: Boolean;π   PROCEDURE ClearKbd;π   PROCEDURE PrintScreen;π   PROCEDURE SetCaps (CapsLock: Boolean);π   PROCEDURE SetEnhKbd (Enhanced: Boolean);π   PROCEDURE SetInsert (Ins: Boolean);π   PROCEDURE SetNum (NumLock: Boolean);π   PROCEDURE SetPrtSc (PrtScOn: Boolean);π   PROCEDURE SetScroll (ScrollLock: Boolean);π   PROCEDURE SpeedKey (RepDelay, RepRate: Integer);π   PROCEDURE TypeIn (Keys: String);ππIMPLEMENTATIONππ{$F+}ππ{ the routines are actually in assembly language }ππ   FUNCTION AltPress; external;π   FUNCTION CapsOn; external;π   FUNCTION CtrlPress; external;π   FUNCTION InsertOn; external;π   FUNCTION LAltPress; external;π   FUNCTION LCtrlPress; external;π   FUNCTION LShiftPress; external;π   FUNCTION NumOn; external;π   FUNCTION RAltPress; external;π   FUNCTION RCtrlPress; external;π   FUNCTION RShiftPress; external;π   FUNCTION ScrollOn; external;π   FUNCTION ShiftPress; external;π   PROCEDURE ClearKbd; external;π   PROCEDURE PrintScreen; external;π   PROCEDURE SetCaps; external;π   PROCEDURE SetEnhKbd; external;π   PROCEDURE SetInsert; external;π   PROCEDURE SetNum; external;π   PROCEDURE SetPrtSc; external;π   PROCEDURE SetScroll; external;π   PROCEDURE SpeedKey; external;π   PROCEDURE TypeIn; external;ππ{$L KBD}ππBEGINπEND.ππ{ ---------------------   CUT HERE -----------------------}ππ1.  CUT THIS OUT TO A SEPARATE FILE.π2.  Name it KBD.XX.π3.  Execute : XX3401 D KBD.XXπ4.  KBD.OBJ will be created.ππHere comes the XX-encoded KBD.OBJ file...ππ*XX3401-001215-010792--68--85-18007---------KBD.OBJ--1-OF--1πU+Y+-qhWN0tVQqrEZUQ+++F1HoF3F7U5+0VT+k6-+RCE6U2++ERHFJF1EJ-HjU++0p-GπGItIIoBGFIJCPE++02ZCIoJGJ2xCAE++0IBIIYlEIYJHImI+++VHFJFEIZFHEqw-++NIπKJ-3GIs2+U+8IoV7FZFEIYJHIy+-++JCJIpDHZo+++hGIoV7FZFEIYJHIuE+++hAIoV7πFZFEIYJHIpA+++ZHFJFHEp7DH2n++E+8H2BIIYlEIYJHIoY+++V1H2J-IYh0F-k+++dGπEpFGH3-GFJBHZU++023AJ3-GFJBH++++0Il-H3FEIYJHIno+++ZGEIlII373IpC4+++4πIoJIHZJBHk2+03B1IYxAH2xCf+++0JB3J2ZCIoJGJ0w-++N1EJ-HHosC+++7IoJIFIt6πGo72rU++03BEFIJ2GoJNw+2+u6U2++0W+R4UsU6-++0o+goKoSXFuB5cUy+-mvE0nFMnπqx1UoC1FotD9h+OmzwoVRTX9h+9B3h5coSW1s+59h+9B3XDPoC1FotD9h-9B3cf2oSW1πs+59h-9B3cf2Uy+-mvE0nFPFu6DU+Qio+goKAxjEsB1UoC1FotD9JJNL9c+y++++REPBπ-JxSLQiQ9jwS++1fx9EGnFO8lB5coSXFu6DU+Qio2goKWgHFuB5cUy+-mvE0nFO1s+59πh+9B3XDPoC1EsB1UoC1FotD9JMjg5ch4-XDPXhg9k5E8U+sL-2+TLQc0+6+a3kGzuzFJπWykSWoM40w-p5Gu+DU+++5EE9gIK++0s3WLB6Gv4-U+++-xRmU6+9c+y++++RTCs3XLBπ6Gu75U++9ck4++0u+++C5vUK7QoV9gM4+++-ux7JWykSWoM4AxiCqkj+R+e+1VQ2U-xRπmU6+U0ML-5zfx3K9v-u9FUMnqsvP0w-o0c+C3kEU5pr8+U0+7VQ2ryjoJMjg5ch4-Uj+πRGkiU1s+++-p5vU3BQoV9cYS+++iX+M++9U37EsTiU++nG2ilUM+++2TLQc0+0u+DU++π+5Hni+IZ9gIK++1B6Gv4-U+++CjVJMjg5ch4-XDPXhg9k5E8U+sL--+TLQc0+6+a3kHjπuzGo+goKAxjFuB5HUy+-0wD9JMjg5cdy06dS-fU3+woK5pr8-+-JWylKJlv3RUMnmTmgπWgWu1k0sE+0Ck9wS+DcaWHsO+9g++8m8s+j+9hRp-2Zo18m4l8h8sCoaWHsQ+DgTLptRπmUE+UDk0RkC+l-+izms++Aw++++++++++++++-sk9W+G6G6X3mEZ7X6l4-YE2lwI3WwFπ9FIg4WgP-kkt+WU2-EM68+c90+on11Ep0k61-+I4-kU70WQbAkooBE6SA0sU2W2W6lQYπ7GMmAFUN2-AT3-Mj2GoJ9-cf4kQA8Fsk9W+G6G6X3mEZ7X6l4-YE2lwI3WwF9FIg4WgPπ8SiQSE12Qp+-KU92UZ+-Kk92v3+-JE92x3+-JU92zZ+-JE930J+-JE933Z+-JU934p+-πK+935Z+-Fk938Z+-JE93TJ+-KU93WZ+-Kk93Xp+-LE93Zp+-J+93bZ+-KU93eJ+-KU93πh3+-Kk93ip+-KU947J+-Lk94IZ+-JU85cUc++Rs0UE++++2+wMc0++-oπ***** END OF XX-BLOCK *****π        55     11-26-9317:21ALL                      SWAG SUPPORT TEAM        Musical Keyboard Handler SWAG9311            18        {πYou'll have to write a new Keyboard hardware interrupt handler, I did thatπ(quite a while ago) for this little program. It generates a different beepπsound for every key pressed. The comments are in Dutch, but if you can readπAfrikaans you might be able to understand them. I think the code is self-πexplanatory anyway.π}ππprogram MusicKey;                                    { herziene versie }ππuses crt, dos;ππconst kbd_data   = $60;                   { Keyboard data poort        }π      kbd_ctrl   = $61;                   { Keyboard control poort     }π      int_ctrl   = $20;                   { Interrupt control poort    }π      eoi        = $20;                   { End-of-interrupt constante }π      release    = $80;                   { Key released bit           }π      enable_kbd = $80;                   { Enable keyboard bit        }ππconst Press      : Byte = 0;    { Scancode van ingedrukte toets        }πvar   SaveInt09  : Pointer;     { Om originele intvector in te bewaren }ππProcedure NewKbdInt; interrupt;        { Interrupt service routine,    }πvar b:Byte;                            { aangeroepen door kbd hardware }πbeginπ  b:=Port[kbd_data];                    { Lees scancode van poort      }π  if b = Press + Release then Press:=0  { Laatst ingedrukte toets los? }π    else if b < Release then Press:=b;  { Toets ingedrukt? Press:=b    }π  b:=Port[kbd_ctrl];                    { Interrupt netjes afwerken    }π  Port[kbd_ctrl]:=b or enable_kbd;π  Port[kbd_ctrl]:=b;π  Port[int_ctrl]:=eoi;πend;ππbeginπ  GetIntVec($9,SaveInt09);                  { Bewaar originele vector  }π  SetIntVec($9,@NewKbdInt);                 { Installeer onze routine  }π{***}π  Writeln(^J^J^M,'Escape = Exit');π  repeatπ    Write(^M,'Gelezen scancode: ',Press:2);     { Druk scancode af     }π    if Press > 1 then Sound(100 * Press)        { Laat toontje horen   }π                 else NoSound;                  { Of niet (Press = 0)  }π  until Press = 1;                              { Escape : Press = 1   }π{***}π  SetIntVec($9,SaveInt09);                  { Herstel originele vector }πend.π                                                                    56     11-02-9305:59ALL                      SWAG SUPPORT TEAM        Nice Keyboard Handler    SWAG9311            21        UNIT KeyIntr;  { support for INT 09 16 routines } { Turbo Pascal 5.5+ }ππINTERFACEππTypeπ  InterruptProcedure = Procedure;ππConstπ  BiosDataSegment = $40;ππProcedure DisableInterrupts; Inline($FA);   { CLI }πProcedure EnableInterrupts;  Inline($FB);   { STI }πProcedure CallInterrupt(P : Pointer);ππFunction AltPressed : Boolean;πFunction ControlPressed : Boolean;πFunction ShiftPressed : Boolean;ππProcedure EOI;                      { end of interrupt to 8259 }πFunction  ReadScanCode : Byte;       { read keyboard }πProcedure ResetKeyboard;            { prepare for next key }π                                     { put key in buffer for INT 16 }πFunction StoreKey(Scan, Key : Byte) : Boolean;ππIMPLEMENTATIONππTypeπ  TwoBytesPtr = ^TwoBytes;π  TwoBytes = Record  { one key in the keyboard buffer }π    KeyCode,π    ScanCode : Byte;π  End;ππVarπ  KeyState       : Word Absolute BiosDataSegment : $17;π  KeyBufferHead  : Word Absolute BiosDataSegment : $1A;π  KeyBufferTail  : Word Absolute BiosDataSegment : $1C;π  KeyBufferStart : Word Absolute BiosDataSegment : $80;π  KeyBufferEnd   : Word Absolute BiosDataSegment : $82;ππProcedure CallInterrupt(P : Pointer);πBeginπ  Inline($9C);           { PUSHF }π  InterruptProcedure(P);πEnd;ππFunction AltPressed : Boolean;πBeginπ  AltPressed := (KeyState and 8) <> 0;πEnd;ππFunction ControlPressed : Boolean;πBeginπ  ControlPressed := (KeyState and 4) <> 0;πEnd;ππFunction ShiftPressed : Boolean;πBeginπ  ShiftPressed := (KeyState and 3) <> 0;πEnd;ππProcedure EOI;  { end of interrupt to 8259 interrupt controller }πBeginπ  Port[$20] := $20;πEnd;ππFunction ReadScanCode : Byte;πVarπ  N : Byte;πBeginπ  N := Port[$60];     { $FF means keyboard overrun }π  ReadScanCode := N;πEnd;ππProcedure ResetKeyboard;      { prepare for next key }πVarπ  N : Byte;πBeginπ  N := Port[$61];π  Port[$61] := (N or $80);π  Port[$61] := N;πEnd;ππFunction StoreKey(Scan, Key : Byte) : Boolean;πVar                { put key in buffer that INT 16 reads }π  P : TwoBytesPtr;π  N : Word;πBeginπ  DisableInterrupts;ππ  N := KeyBufferTail;π  P := Ptr(BiosDataSegment, N);ππ  Inc(N, 2);π  If(N = KeyBufferEnd) then        { end of the circular buffer }π    N := KeyBufferStart;π  If(N = KeyBufferHead) then       { buffer full }π  Beginπ    EnableInterrupts;π    StoreKey := False;π  Endπ  Elseπ  Beginπ    P^.KeyCode := Key;π    P^.ScanCode := Scan;             { store key in circular buffer }π    KeyBufferTail := N;              { advance tail pointer }π    EnableInterrupts;π    StoreKey := True;π  End;πEnd;πππEND.ππππ                 57     11-26-9317:14ALL                      SWAG SUPPORT TEAM        Nice Keyboard unit       SWAG9311            103       πUnit keybx;π π interfaceπ π uses errors;π π π const     Right_shift     = $0001;π           Left_shift      = $0002;π           Ctrl            = $0004;π           Alt             = $0008;π           Scroll_locked   = $0010;π           Num_locked      = $0020;π           Caps_locked     = $0040;π           Insert_locked   = $0080;π π           Right_ctrl      = $0100;π           left_alt        = $0200;π           sysreq          = $0400;π           Pause_locked    = $0800;π           Scroll_pressed  = $1000;π           Num_pressed     = $2000;π           Caps_pressed    = $4000;π           Ins_pressed     = $8000;π π           Space           = $3920;π π           Enter           = $1C0D;π           Ctrl_Enter      = $1C0A;π           Shift_Enter     = $1C0D;π           Alt_Enter       = $1C00;π π           gray_Enter      = $E00D;π           Ctrl_Gray_Enter = $E00A;π           Shift_Gray_Enter= $E00D;π           Alt_Gray_Enter  = $A600;ππ           gray_Plus       = $4E2B;π           Ctrl_gray_plus  = $9000;π           Shift_gray_plus = $4E2B;π           alt_gray_plus   = $4E00;π π           gray_Minus      = $4A2D;π           Ctrl_gray_minus = $8E00;π           Shift_gray_minus= $4A2D;π           alt_gray_minus  = $4A00;π π           _Esc            = $011B;π           Ctrl_Esc        = $011B;π           Shift_Esc       = $011B;π           Alt_Esc         = $0100;π π           Backspace       = $0E08;π           Ctrl_Backspace  = $0E7F;π           Shift_Backspace = $0E08;π           Alt_Backspace   = $0E00;ππ π           _Tab            = $0F09;π           Ctrl_Tab        = $9400;π           Shift_Tab       = $0F00;π           Alt_Tab         = $A500;π π           _Up             = $4800;π           _Down           = $5000;π           _Left           = $4B00;π           _Right          = $4D00;π           _Home           = $4700;π           _End            = $4F00;π           _PgUp           = $4900;π           _PgDn           = $5100;π           _Five           = $4C00;π           _Ins            = $5200;π           _del            = $5300;π π           Ctrl_Up         = $8D00;π           Ctrl_Down       = $9100;π           Ctrl_Left       = $7300;π           Ctrl_Right      = $7400;π           Ctrl_Home       = $7700;π           Ctrl_End        = $7500;π           Ctrl_PgUp       = $8400;π           Ctrl_PgDn       = $7600;π           Ctrl_Five       = $8F00;π           Ctrl_Del        = $9300;π           Ctrl_Ins        = $9200;π π π           shift_Up        = $4838;π           shift_Down      = $5032;π           shift_Left      = $4B34;π           shift_Right     = $4D36;π           shift_Home      = $4737;π           shift_End       = $4F31;π           shift_PgUp      = $4939;π           shift_PgDn      = $5133;π           shift_Five      = $4C35;π           shift_ins       = $5230;π           shift_del       = $532E;π π           gray_Up         = $48E0;π           gray_Down       = $50E0;π           gray_Left       = $4BE0;π           gray_Right      = $4DE0;π           gray_Home       = $47E0;π           gray_End        = $4FE0;π           gray_PgUp       = $49E0;π           gray_PgDn       = $51E0;π           gray_ins        = $52E0;π           gray_del        = $53E0;π π           Ctrl_gray_Up    = $8DE0;π           Ctrl_gray_Down  = $91E0;π           Ctrl_gray_Left  = $73E0;π           Ctrl_gray_Right = $74E0;π           Ctrl_gray_Home  = $77E0;π           Ctrl_gray_End   = $75E0;π           Ctrl_gray_PgUp  = $84E0;π           Ctrl_gray_PgDn  = $76E0;π           Ctrl_Gray_Ins   = $92E0;π           Ctrl_Gray_del   = $93E0;π π           shift_gray_Up   = $48E0;π           shift_gray_Down = $50E0;π           shift_gray_Left = $4BE0;π           shift_gray_Right= $4DE0;π           shift_gray_Home = $47E0;π           shift_gray_End  = $4FE0;π           shift_gray_PgUp = $49E0;π           shift_gray_PgDn = $51E0;π           Shift_gray_Ins  = $52E0;π           Shift_gray_del  = $53E0;π π           Alt_gray_Up     = $9800;π           Alt_gray_Down   = $A000;π           Alt_gray_Left   = $9B00;π           Alt_gray_Right  = $9D00;π           Alt_gray_Home   = $9700;π           Alt_gray_End    = $9F00;π           Alt_gray_PgUp   = $9900;π           Alt_gray_PgDn   = $A100;π           Alt_gray_Ins    = $A200;π           Alt_gray_del    = $A300;π π           _f1             = $3B00;π           _f2             = $3C00;π           _f3             = $3D00;π           _f4             = $3E00;π           _f5             = $3F00;π           _f6             = $4000;π           _f7             = $4100;π           _f8             = $4200;π           _f9             = $4300;π           _f10            = $4400;π           _f11            = $8500;π           _f12            = $8600;ππ           Shift_f1        = $5400;π           Shift_f2        = $5500;π           Shift_f3        = $5600;π           Shift_f4        = $5700;π           Shift_f5        = $5800;π           Shift_f6        = $5900;π           Shift_f7        = $5A00;π           Shift_f8        = $5B00;π           Shift_f9        = $5C00;π           Shift_f10       = $5D00;π           Shift_f11       = $8700;π           Shift_f12       = $8800;π π           Ctrl_f1         = $5E00;π           Ctrl_f2         = $5F00;π           Ctrl_f3         = $6000;π           Ctrl_f4         = $6100;π           Ctrl_f5         = $6200;π           Ctrl_f6         = $6300;π           Ctrl_f7         = $6400;π           Ctrl_f8         = $6500;π           Ctrl_f9         = $6600;π           Ctrl_f10        = $6700;π           Ctrl_f11        = $8900;π           Ctrl_f12        = $8A00;π π           Alt_f1          = $6800;π           Alt_f2          = $6900;π           Alt_f3          = $6A00;π           Alt_f4          = $6B00;π           Alt_f5          = $6C00;π           Alt_f6          = $6D00;π           Alt_f7          = $6E00;π           Alt_f8          = $6F00;π           Alt_f9          = $7000;π           Alt_f10         = $7100;π           Alt_f11         = $8B00;π           Alt_f12         = $8C00;π π           Alt_a           = $1E00;π           Alt_b           = $3000;π           Alt_c           = $2E00;π           Alt_d           = $2000;π           Alt_e           = $1200;π           Alt_f           = $2100;π           Alt_g           = $2200;π           Alt_h           = $2300;π           Alt_i           = $1700;π           Alt_j           = $2400;π           Alt_k           = $2500;π           Alt_l           = $2600;π           Alt_m           = $3200;π           Alt_n           = $3100;π           Alt_o           = $1800;π           Alt_p           = $1900;π           Alt_q           = $1000;π           Alt_r           = $1300;π           Alt_s           = $1F00;π           Alt_t           = $1400;π           Alt_u           = $1600;π           Alt_v           = $2F00;π           Alt_w           = $1100;π           Alt_x           = $2D00;π           Alt_y           = $1500;π           Alt_z           = $2C00;π π           Ctrl_a          = $1E01;π           Ctrl_b          = $3002;π           Ctrl_c          = $2E03;π           Ctrl_d          = $2004;π           Ctrl_e          = $1205;π           Ctrl_f          = $2106;π           Ctrl_g          = $2207;π           Ctrl_h          = $2308;π           Ctrl_i          = $1709;π           Ctrl_j          = $240A;π           Ctrl_k          = $250B;π           Ctrl_l          = $260C;π           Ctrl_m          = $320D;π           Ctrl_n          = $310E;π           Ctrl_o          = $180F;π           Ctrl_p          = $1910;π           Ctrl_q          = $1011;π           Ctrl_r          = $1312;π           Ctrl_s          = $1F13;π           Ctrl_t          = $1414;π           Ctrl_u          = $1615;π           Ctrl_v          = $2F16;π           Ctrl_w          = $1117;π           Ctrl_x          = $2D18;π           Ctrl_y          = $1519;π           Ctrl_z          = $2C1A;π π π           Key_a           = $1E61;π           Key_b           = $3062;π           Key_c           = $2E63;π           Key_d           = $2064;π           Key_e           = $1265;π           Key_f           = $2166;π           Key_g           = $2267;π           Key_h           = $2368;π           Key_i           = $1769;π           Key_j           = $246A;π           Key_k           = $256B;π           Key_l           = $266C;π           Key_m           = $326D;π           Key_n           = $316E;π           Key_o           = $186F;π           Key_p           = $1970;π           Key_q           = $1071;π           Key_r           = $1372;π           Key_s           = $1F73;π           Key_t           = $1474;π           Key_u           = $1675;π           Key_v           = $2F76;π           Key_w           = $1177;π           Key_x           = $2D78;π           Key_y           = $1579;π           Key_z           = $2C7A;π π           Key_0           = $0B30;π           Key_1           = $0231;π           Key_2           = $0332;π           Key_3           = $0433;π           Key_4           = $0534;π           Key_5           = $0635;π           Key_6           = $0736;π           Key_7           = $0837;π           Key_8           = $0938;π           Key_9           = $0A39;π π π           Shift_Key_a     = $1E41;π           Shift_Key_b     = $3042;π           Shift_Key_c     = $2E43;π           Shift_Key_d     = $2044;π           Shift_Key_e     = $1245;π           Shift_Key_f     = $2146;π           Shift_Key_g     = $2247;π           Shift_Key_h     = $2348;π           Shift_Key_i     = $1749;π           Shift_Key_j     = $244A;π           Shift_Key_k     = $254B;π           Shift_Key_l     = $264C;π           Shift_Key_m     = $324D;π           Shift_Key_n     = $314E;π           Shift_Key_o     = $184F;π           Shift_Key_p     = $1950;π           Shift_Key_q     = $1051;π           Shift_Key_r     = $1352;π           Shift_Key_s     = $1F53;π           Shift_Key_t     = $1454;π           Shift_Key_u     = $1655;π           Shift_Key_v     = $2F56;π           Shift_Key_w     = $1157;π           Shift_Key_x     = $2D58;π           Shift_Key_y     = $1559;π           Shift_Key_z     = $2C5A;ππ           Shift_Key_0     = $0B29;π           Shift_Key_1     = $0221;π           Shift_Key_2     = $0340;π           Shift_Key_3     = $0423;π           Shift_Key_4     = $0524;π           Shift_Key_5     = $0625;π           Shift_Key_6     = $075E;π           Shift_Key_7     = $0826;π           Shift_Key_8     = $092A;π           Shift_Key_9     = $0A28;π π           No_Key_At_all   = $FFFF;π           No_Key          = $FFFE;π           Ctrl_Break      = $0000;π π π function  Readkey:char;π function  keypressed:boolean;π π function  Extended_Keypressed:boolean;π function  Extended_Readkey:word;π procedure Extended_Writekey(scan_code:word);π function  Extended_Browsekey:word;π procedure Flush_That_Key;π π function  Ctrl_Break_pressed:boolean;π procedure Clear_Ctrl_Break;π π function  get_shift_status:word;π function  shift_status_is(mask:word):boolean;π function  Get_char(w:word):char;π π π Var Touche_Residuelle:byte;π     Last_key:word;π π π implementationπ π (*===========*)π function  Get_char(w:word):char; assembler;π  asmπ   mov ax,wπ  end;π π (*===========*)π function  Readkey:char; assembler;π  asmπ   mov al,Touche_residuelleπ   or  al,alπ   jz  @iciπ   mov touche_residuelle,0π   jmp @exitπ   @ici:π   mov ah,$10π   int $16π   mov last_key,axπ   or  al,alπ   jnz @exitπ   mov Touche_residuelle,ahπ   @exit:π  end;π π π (*===========*)π function  keypressed:boolean; assembler;π  asmπ   mov ah,$11π   int $16π   mov al,0π   jz  @exitπ   mov al,1π   @exit:π  end;π π π (*===========*)π function get_shift_status:word; assembler;π  asmπ   xor ax,axπ   mov es,axπ   mov ax,es:[$417]π  end;π π (*===========*)π function  shift_status_is(mask:word):boolean; assembler;π  asmπ   xor ax,axπ   mov es,axπ   mov ax,es:[$417]π   and ax,maskπ   jz  @exitπ   mov al,1π   @exit:π  end;π π π (*===========*)π procedure Clear_Ctrl_Break; assembler;π  asmπ   xor ax,axπ   mov es,axπ   mov byte ptr es:[$471],0π  end;π π π (*===========*)π function Ctrl_Break_pressed:boolean; assembler;π  asmπ   xor ax,axπ   mov es,axπ   mov al,es:[$471]π   shr al,7π  end;π π π (*===========*)π function extended_keypressed:boolean; assembler;π  asmπ   mov ah,$11π   int $16π   lahfπ   and ah,$4π   not ahπ   mov al,ahπ  end;π π (*===========*)π function  Extended_Browsekey:word; assembler;π  asmπ   mov ah,$11;π   int $16π   jnz @exitπ   xor ax,axπ   @exit:π  end;π π (*===========*)π function extended_readkey:word; assembler;π  asmπ   mov ah,$10π   int $16π   mov last_key,axπ  end;π π (*===========*)π procedure flush_that_key; assembler;π  asmπ   mov ah,$10π   int $16π  end;π π (*===========*)π procedure extended_writekey(scan_code:word); assembler;π  asmπ   mov ah,5π   mov cx,scan_codeπ   int $16π  end;π π π π beginπ  Touche_residuelle:=0;π  Last_key:=no_key_at_all;π  Clear_Ctrl_Break;π end.ππ